How I made a new, very hard logic puzzle using Julia

Here’s how I used Julia to make possibly one of the most difficult logic puzzles ever made. This one is truly diabolical.

The question is that there are four gods, true, lie, rand, and rock.

You can ask three questions. They will answer with a red light or a green light. One is true, and one is false, but you don’t know which one.

True will always answer the truth.

Lie will always answer the lie.

Rand will hash the question and use that to decide whether to play as true or lie. Rand will always answer the same answer for the same question, but you won’t know how Rand hashes the question.

Rock will never answer anything.

If the question cannot be answered, everyone will stay silent.

Find who is true, who is lie, who is rand, and who is rock.

Spoiler 1:

#The question would be in the form,

#If the gods don’t know the word “true” and “false”, add these two lines.

#Let “true” mean that I would get green if I asked “If you were asked if 1+1=2, would you answer green, is green”

#Let “false” mean that I would get green if I asked “If you were asked if 1+1=2, would you answer green, is red”

#Let x be the statement "if you were asked if either the permutation is in a set of (TRUE permutation), "

#Let y be the statement “if you were asked if either the permutation is in a set of (SILENT permutation)”

#Let z be the statement "The truthfulness of the answer to this question if you were always saying the truth is equal to false,

#where this question refers to the question I’m asking you right now."

#If you were asked if the truthfulness of x is true or the truthfulness of both y and z are true, would you answer green?

#True’s reasoning, if green=true.

If the permutation is in the (TRUE) permutation, you can answer green.

If the permutation is in the (SILENT) permutation, then you can’t answer so you would remain silent.

Otherwise, you will answer red.

#True’s reasoning, if green=false

If the permutation is in the (TRUE) permutation, you would still answer green. (y is not true)

IF the permutation is in the (SILENT) permutation, you would still remain silent. (if z is true, then you need to answer false, but you need to answer true, and vice versa. )

#Lie’s reasoning, if green = true.

If the permutation is in the (TRUE) permutation, you can also answer green. (y is not true), Lie would always lie and answer red, but then lie about the answer again and answer green.

If the permutation is in the (SILENT) permutation, you also can’t answer. (z gets evaluated in the same way, that is, paradoxical)

#Lie’s reasoning, if green = false.

If the permutation is in the (TRUE) permutation, you can also answer green. (y is not true), Lie would always lie and answer red, but then lie about the answer again and answer green.

If the permutation is in the (SILENT) permutation, you also can’t answer. (z gets evaluated in the same way, that is, paradoxical)

random, when asked a question, will hash the question to pick to play as true or lie. The same question always lead to the same answer.

#However, you cannot know the hash in advance. However, you can still make it stay silent by asking a question that resolves to a paradox.

#This means if we ask True or Lie, we can always get the answer that divides the permutation into three groups.

Spoiler 2: the code I used to interactively solve the puzzle. (Please note that I edited this code many times.

function recur(perms,question_left,cache)
    if length(perms) <= 1 || perms in cache
        return true
    end
    
    if question_left == 3
        random_numbers = #Something, spoiler.
        
        god_to_ask = 0
    else
        random_numbers = rand(1:3,length(perms))
        god_to_ask = rand(0:3)
    end
    

    
    if 3^question_left < length(perms) #Impossible to solve.
        return false
    end

    
    green = Vector{eltype(perms)}()
    red = Vector{eltype(perms)}()
    silent = Vector{eltype(perms)}()
    for (idx,i) in enumerate(perms)
        true_position = i[1]
        lie_position = i[2]
        rand_position = i[3]
        if (god_to_ask == true_position) | (god_to_ask == lie_position)
            if (random_numbers[idx] == 1)
                push!(green,i)
            elseif (random_numbers[idx] == 2)
                push!(red,i)
            else
                push!(silent,i)
            end
        elseif (god_to_ask == rand_position)
            if (random_numbers[idx] == 3)
                push!(silent,i)
            else
                push!(green,i)
                push!(red,i)
            end
        else
            push!(silent,i)
        end
    end
    #println(random_numbers)
    #println(green)
    #println(red)
    #println(silent)
    
    
    if (length(silent) == 3) & (length(green) == 3) & (length(red) == 3)
        println(god_to_ask)
        println(random_numbers)
        println(green)
        println(red)
        println(silent)
    end
    

    if recur(green,question_left-1,cache) && recur(red,question_left-1,cache) && recur(silent,question_left-1,cache)
        push!(cache,perms)
        return true
    end
    return false
    #return recur(green,question_left-1) && recur(red,question_left-1) && recur(silent,question_left-1)
end

Spoiler 3:

Start with permutation: where each number(0-indexed) tells you the true, lie, rand, and rock’s position respectively.
(1, 0, 2, 3)

(2, 0, 1, 3)

(3, 0, 1, 2)

(0, 2, 3, 1)

(1, 2, 3, 0)

(2, 1, 3, 0)

(3, 1, 2, 0)

(0, 3, 1, 2)

(1, 3, 0, 2)

(2, 3, 0, 1)

(3, 2, 0, 1)

(0, 1, 3, 2)

(1, 0, 3, 2)

(2, 0, 3, 1)

(3, 0, 2, 1)

(0, 2, 1, 3)

(1, 2, 0, 3)

(2, 1, 0, 3)

(3, 1, 0, 2)

(0, 3, 2, 1)

(1, 3, 2, 0)

(2, 3, 1, 0)

(3, 2, 1, 0)

(0, 1, 2, 3)

You ask god at position 1

[1, 2, 2, 2, 2, 1, 2, 1, 3, 3, 1, 1, 1, 1, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1]

Green:
[(1, 0, 2, 3), (0, 3, 1, 2), (3, 2, 0, 1), (0, 1, 3, 2), (1, 0, 3, 2), (2, 0, 3, 1), (1, 2, 0, 3), (3, 1, 0, 2), (0, 1, 2, 3)]
Red:
[(2, 0, 1, 3), (3, 0, 1, 2), (0, 2, 3, 1), (3, 2, 0, 1), (3, 0, 2, 1), (0, 2, 1, 3), (1, 2, 0, 3), (3, 1, 0, 2), (0, 3, 2, 1)]
Silence:
[(1, 2, 3, 0), (2, 1, 3, 0), (3, 1, 2, 0), (1, 3, 0, 2), (2, 3, 0, 1), (2, 1, 0, 3), (1, 3, 2, 0), (2, 3, 1, 0), (3, 2, 1, 0)]

First case
[(1, 0, 2, 3), (0, 3, 1, 2), (3, 2, 0, 1), (0, 1, 3, 2), (1, 0, 3, 2), (2, 0, 3, 1), (1, 2, 0, 3), (3, 1, 0, 2), (0, 1, 2, 3)]
You ask god at position 2
[2, 3, 2, 2, 1, 3, 2, 1, 1]
Green
[(1, 0, 3, 2), (3, 1, 0, 2), (0, 1, 2, 3)] In this case, you ask god at position 1, who is either true or lie.
Red
[(1, 0, 2, 3), (0, 1, 3, 2), (1, 2, 0, 3)] In this case, you ask god at position 1, who is either true or lie.
Silence
[(0, 3, 1, 2), (3, 2, 0, 1), (2, 0, 3, 1)] In this case, you ask god at position 1,
with the silent case reserved to the case where the god is random.

Second case:
[(2, 0, 1, 3), (3, 0, 1, 2), (0, 2, 3, 1), (3, 2, 0, 1), (3, 0, 2, 1), (0, 2, 1, 3), (1, 2, 0, 3), (3, 1, 0, 2), (0, 3, 2, 1)]
You ask god at position 1

[2, 2, 2, 3, 1, 1, 3, 3, 1]

Green
[(3, 0, 2, 1), (0, 2, 1, 3), (0, 3, 2, 1)] In this case, you ask god at position 1, who is either true or lie.
Red
[(2, 0, 1, 3), (3, 0, 1, 2), (0, 2, 3, 1)] In this case, you ask god at position 1, who is either true or lie.
Silence
[(3, 2, 0, 1), (1, 2, 0, 3), (3, 1, 0, 2)] In this case, you ask god at position 4, who is either true or rock.

Third case
[(2, 0, 1, 3), (3, 0, 1, 2), (0, 2, 3, 1), (3, 2, 0, 1), (3, 0, 2, 1), (0, 2, 1, 3), (1, 2, 0, 3), (3, 1, 0, 2), (0, 3, 2, 1)]
You ask god at position 1
[2, 2, 2, 3, 1, 1, 3, 3, 1]
Green:
[(3, 0, 2, 1), (0, 2, 1, 3), (0, 3, 2, 1)] In this case, you ask god at position 1, who is either true or lie.
Red:
[(2, 0, 1, 3), (3, 0, 1, 2), (0, 2, 3, 1)] In this case, you ask god at position 1, who is either true or lie.
Silence:
[(3, 2, 0, 1), (1, 2, 0, 3), (3, 1, 0, 2)] In this case, you ask god at position 4, who is either true or rock.