20
$\begingroup$

This puzzle is part of the Puzzling StackExchange Advent Calendar 2021. The accepted answer to this question will be awarded a bounty worth 50 reputation.

< Previous Door Next Door >


Question: What message is hidden inside this tree?

triangle with asterisks, spaces, greater and less than signs, upper and lowercase O’s and @ symbols.

Text Version:

               *
              >​>​>​
             >​>​>​O​>​
            >​O​<​O​>​o​@​
           O​>​o​>​o​>​>​O​@​
          >​>​@​<​O​>​o​<​@​>​>​
         @​O​>​o​@​O​<​o​<​@​<​<​@​
        O​<​<​<​o​>​>​>​@​O​<​<​<​o​<​
       o​<​O​<​@​>​>​>​O​>​>​>​o​>​@​>​>​
      >​>​>​O​>​o​@​O​<​<​o​@​<​O​>​o​@​>​>​
     O​<​<​<​<​o​@​O​<​<​<​<​<​o​>​o​>​>​@​O​<​
    o​<​<​O​@​>​>​>​>​>​O​<​<​<​<​o​@​O​<​o​@​>​<​
   <​<​<​<​<​<​<​@​>​O​<​o​>​>​>​@​>​O​>​>​>​>​>​>​o​
  >​@​O​>​>​o​<​@​O​>​>​o​@​<​O​>​>​>​o​<​o​>​>​@​O​<​<​
 o​>​>​>​>​>​@​<​<​O​>​o​<​o​>​>​@​>​>​>​>​O​>​o​@​<​O​>​>​
o​>​>​@​O​<​<​<​<​o​@​O​>​>​o​>​<​>​<​<​>​>​<​<​>​>​>​<​>​<​@​

Note:

The asterisk (and the leading spaces) are for decoration only.


Small Hint:

dan04 is correct in their assumption that the tree is executable. ;) You won’t find the solution by digging through a list of existing esolangs (or at least I really hope so).

The language, unsurprisingly, has a “Print” command.

Medium Hint:

- O/o are not bracketed groups.
- Output depends on ASCII code points.
- I had to be very careful with my wording in the original note.
- The commands are very simple.

Large Hint:

Which line a command is on influences its result (except if the command is @).

Between two @s, you will often find a structure of the form O{x times > or <}o. This is a “trick” that does a very simple operation. It’s employed to compensate for what \n does.

Maybe you should focus on the start, which gets us to a printable ASCII letter in (14+3) commands.

Some confirmations of what people have said:
- @ = print value as char
- > = increment value (somehow)
- < = decrement value (somehow)

$\endgroup$
10
  • 8
    $\begingroup$ Asterisks are for decoration No, without a star it's not christmas tree! ... Wait, yes, it's for decoration ... $\endgroup$
    – WhatsUp
    Dec 2, 2021 at 9:27
  • 2
    $\begingroup$ A christmas tree without a star is NOT a christmas tree, even with other decorations. $\endgroup$
    – Stevo
    Dec 2, 2021 at 9:34
  • 2
    $\begingroup$ In case it's helpful information to anyone, the tree contains 95 >s, 65 <s, 32 Os, 32 os, and 31 @s. $\endgroup$
    – dan04
    Dec 2, 2021 at 17:15
  • 4
    $\begingroup$ @Avi: I suspect that it actually is some kind of esoteric programming language like that. I also see that the characters O and o form balanced "brackets". $\endgroup$
    – dan04
    Dec 2, 2021 at 17:23
  • 3
    $\begingroup$ @hb20007 Yep, that's the inspiration :) I have no idea what the AOC tree does or how its generated, though. That's independent from this puzzle. $\endgroup$ Dec 3, 2021 at 10:27

4 Answers 4

11
+50
$\begingroup$

Thanks to @Crimsonfox, the complete answer is:

Christmas Comes But Once a Year

The corresponding ASCII code points we get by running the commands are:

67 104 114 105 115 116 109 97 115 32 67 111 109 101 115 32 66 117 116 32 79 110 99 101 32 97 32 89 101 97 114


To solve the puzzle, I created the tiny JavaScript program below. The code iterates through all the characters of the string (the asterisk and spaces are removed), assigning a specific command to each symbol.

var input =
    "\n" +
    ">>>\n" +
    ">>>O>\n" +
    ">O<O>o@\n" +
    "O>o>o>>O@\n" +
    ">>@<O>o<@>>\n" +
    "@O>o@O<o<@<<@\n" +
    "O<<<o>>>@O<<<o<\n" +
    "o<O<@>>>O>>>o>@>>\n" +
    ">>>O>o@O<<o@<O>o@>>\n" +
    "O<<<<o@O<<<<<o>o>>@O<\n" +
    "o<<O@>>>>>O<<<<o@O<o@><\n" +
    "<<<<<<<@>O<o>>>@>O>>>>>>o\n" +
    ">@O>>o<@O>>o@<O>>>o<o>>@O<<\n" +
    "o>>>>>@<<O>o<o>>@>>>>O>o@<O>>\n" +
    "o>>@O<<<<o@O>>o><><<>><<>>><><@";

var output = [],
    x = 0,
    line = 0;

for(var i = 0; i < input.length; i++) {
    if(input[i] === ">") {
        // increment value
        x += line;
    } else if(input[i] === "<") {
        // decrement value
        x -= line;
    } else if(input[i] === "O") {
        // multiply by line number
        x *= line;
    } else if(input[i] === "o") {
        // divide by line number and round off
        x = Math.floor(x / line);
    } else if(input[i] === "@") {
        // print ASCII character
        output.push(x);
    } else if(input[i] === "\n") {
        // increment line number
        line++;
    }
}

console.log(String.fromCharCode(...output));

As we can see, we need to do four simple arithmetic operations in order to decode the Christmas tree: addition (>), subtraction (<), multiplication (O) and division (o), using the line number of the corresponding command. @ prints the value of x which represents an ASCII code point.


Original answer

Note: Since this used to be a partial answer, some of the information below might be incorrect.

The hints provided in the question (and one of OP’s comments) let us conclude the following:

As stated in the “large hint,” < and > are used to increment and decrement a variable by a certain value, while @ means “print ASCII character.”

O/o are not bracketed groups. Between two @s, you will often find a structure of the form O{x times > or <}o. This is a “trick” that does a very simple operation.
O/o do not represent brackets or parenthesis. However, O{…}o seems to imply that O and o do come in pairs and thus probably have a similar purpose. Since each of the five different symbols represent a “very simple operation,” we should probably focus on simple additions (or subtractions) rather than multiplications and divisions.
It's employed to compensate for what \n does. The difference between the number of O and o should turn out to be small, if not 0.
→ This suggests that O and o represent a particular number and have something to do with line numbers. Since O adds 1 to the line variable and o subtracts the same number in the code above, we can say there is only little difference between the two commands.

Which line a command is on influences its result (except if the command is @).
→ The variable line in the code must somehow be involved in incrementing and decrementing the value x. In the example above, a > on line 4 increments x by 4, while a < decrements it by 4. @ simply outputs the value of the counter x.

Maybe you should focus on the start, which gets us to a printable ASCII letter in (14+3) commands.
→ There are exactly 14 symbols or commands before the first print command (@), excluding line breaks, as well as 3 Os: >>>>>>O>>O<O>o. We have make sure x is between 65 (A) and 90 (Z) (or 97 and 122 for the lowercase letters), so that the commands yield a valid letter of the alphabet.

I had to be very careful with my wording in the original note. (The asterisk (and the leading spaces) are for decoration only.)
→ If OP had written “whitespaces” instead of “spaces,” that would mean we could also ignore line breaks and line numbers, which is not the case, according to the hints.

Now, the question arises whether >/< and O/o really constitute two separate counters that can be incremented and decremented.

$\endgroup$
4
  • 1
    $\begingroup$ Every command except O and o is implemented correctly. $\endgroup$ Dec 4, 2021 at 16:43
  • $\begingroup$ How are you getting from 115 to 32? I come out at 33. L7 O<<<o<\n 805 784 112 105 L8 o<O<@ 13.125 5.125 41 33 $\endgroup$
    – Crimsonfox
    Dec 4, 2021 at 18:09
  • 2
    $\begingroup$ @Crimsonfox Integer division, i.e. division where the remainder gets discarded. $\endgroup$ Dec 4, 2021 at 18:16
  • $\begingroup$ @Lukas Rotter Of course, of course, silly me $\endgroup$
    – Crimsonfox
    Dec 4, 2021 at 18:21
10
+100
$\begingroup$

I think I’ve got it, just working through the message, the first letters are coming out as expected. The commands map as follows:

< / >: increment and decrement by line number
\n: increment line number variable
@: print
O / o: multiply and divide by line number

The first word is Christmas. Edit: I’m having trouble with that should be a space, coming out 1 character too high. But if I skip it (or assume it’s a space) I get Comes as the second word.

Edit 2: Answer is “Christmas Comes But Once a Year” because I’m silly and forgot to floor it.

$\endgroup$
2
  • 4
    $\begingroup$ I'll accept Lypyrhythm's answer because it provides a better explanation. But since you are the one who actually solved this, I'll just award a 100 points bounty to you (independent from the event) $\endgroup$ Dec 4, 2021 at 18:38
  • $\begingroup$ @Lukas Rotter Thanks! Wasn't expected to get so invested in this, great puzzle! $\endgroup$
    – Crimsonfox
    Dec 4, 2021 at 18:40
5
$\begingroup$

Partial answer

The tree is a program in an esoteric program language, which has at least one state variable (which I'll call “the accumulator”), and 5 commands:

  • > / < = increment/decrement the accumulator
  • @ = print a character whose value is somehow related to the accumulator's value (likely ASCII code, or a simple 1=A, 2=B, 3=C, ..., 26=Z code).
  • O ... o = a bracketed group of instructions, perhaps representing a while or for loop.

Whitespace and * are ignored.

Edit: My original idea about O and o was disproven by the Medium Hint. But I still think it's some kind of complementary pair of commands.

$\endgroup$
10
  • 2
    $\begingroup$ Good observations. I got Brainf**k vibes from this at first sight and mapping Oo><@ to Oo+-. makes a valid program, but it writes unprintable characters. (This doesn't make use of loops or jumps, but we either get a program with just one register or a program without loops.) Anyway, we can write a program that writes numbers instead of ASCII codes. (Not having loops means that going into the useful range of ASCII characters will be very verbose.) In honour of Lukas, we could call this bf variant Brainrot. :) Unfortunaltely, I don't know what to do next. $\endgroup$
    – M Oehm
    Dec 3, 2021 at 5:45
  • 1
    $\begingroup$ I'll spoiler that O/o are not bracketed groups $\endgroup$ Dec 3, 2021 at 6:24
  • 1
    $\begingroup$ @dan04 Strictly speaking it's coincidental, but it's a coincidence that's likely to happen if you write code in this language (if it outputs anything that makes sense). The difference between the number of O and o should turn out to be small, if not 0. $\endgroup$ Dec 3, 2021 at 8:34
  • 1
    $\begingroup$ Why do you think that < and > change the accumulator? It could be e.g. moving the read/write pointer, as in a Turing machine. Also why is @ printing characters? This looks like pure guessing to me - so is the entire puzzle actually, for such a computer puzzle I would prefer something that involves a little bit of logical reasoning. $\endgroup$
    – WhatsUp
    Dec 3, 2021 at 8:43
  • 2
    $\begingroup$ @WhatsUp The last command is @, so unless that is the print command we're leaving something out of the output. $\endgroup$
    – Jafe
    Dec 3, 2021 at 8:50
2
$\begingroup$

I also assumed @ prints a character based on an accumulated value

If < and > increment and decrement a register that starts as 0 then throughout the program the register varies between 0 and 31.

If O and o increment and decrement a different register that starts as 0 then throughout the program the register varies between 0 and 3.

These seem to be independently covering 5 bits and 2 bits. If you concatenate the values the 2 bits above the 5 bits then it outputs valid capital ASCII characters and one dash for the first 24 characters, two digits for the next two and then 5 non printing characters. Unfortunately it does not spell anything.

The hint "I had to be very careful with my wording in the original Note." makes me think that while the asterisk(s) and space mean nothing, maybe the line breaks affect the program somehow.

$\endgroup$
5
  • $\begingroup$ So, if I understand correctly, you got the output "HLNMOPNLLFMSQQO-JKJCFNOQ47␗␜␟␛␀". $\endgroup$
    – dan04
    Dec 3, 2021 at 9:29
  • $\begingroup$ @dan04 Correct. $\endgroup$
    – caPNCApn
    Dec 3, 2021 at 21:45
  • $\begingroup$ What do you mean by “concatenate the values the 2 bits above the 5 bits”? For example, if i = 11 and j = 2, should the result be concat(j, i), i.e. 211? $\endgroup$
    – user47620
    Dec 4, 2021 at 8:02
  • 1
    $\begingroup$ @Lypyrhythm: If means that if x is the 5-bit register and o is the 2-bit register, then their combined value is (o << 5) | x or 32 * o + x. $\endgroup$
    – dan04
    Dec 4, 2021 at 8:11
  • 1
    $\begingroup$ It means that O would be equivalent to a sequence of 32 >s, and o to a sequence of 32 <s. Or maybe vice-versa. Or maybe they represent a different related pair of operations like double and halve. $\endgroup$
    – dan04
    Dec 4, 2021 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.