CrackTheCode.frink

View or download CrackTheCode.frink in plain text format


/** This program cracks a lock from a puzzle posted here:
    https://twitter.com/vardi/status/1164204994624741376

    The solution is based on the mastermind.frink program that plays the game
    Mastermind.

   Its algorithm is very simple:

   1.) Make a list of all possible combinations

   2.) Take one given result and eliminate all of the
       plays from the list that can't match that feedback.  Repeat until done.
*/


// The possible numbers.  You can change these to whatever you want, including
// full names.  You can also use more or fewer numbers and everything will
// just work right.
colors=array[0 to 9]

// You can change from a 3-digit combination to an arbitrary number of pegs.
numDigits = 3

// Create an array with all possible plays.
opts = new array
multifor x = makeArray[[numDigits], colors]
   opts.push[x]

// This is a function that will be passed to "select".  It just returns true
// for each combination that matches the specified result.
sfunc =  {|combination, data|
          [target, result] = data
          rank[combination, target] == result
         }

plays = [[[6,8,2], [1,0]],
         [[6,1,4], [0,1]],
         [[2,0,6], [0,2]],
         [[7,3,8], [0,0]],
         [[7,8,0], [0,1]]]
         
// The main loop.
for [combination, result] = plays
{
   print["Possible solutions remaining:   " + length[opts]]
   println["\tTesting $combination"]

   // Now just go through the remaining possible solutions and return only
   // the ones that could have matching results.
   opts = array[select[opts,
                       sfunc,
                       [combination, result]]]
}

println["Solution[s] are " + opts]


/** This function determines how good a combination was at matching the
    specified target.  It returns the number of black and white pegs as the
    array
    [black, white]
*/

rank[combination, target] :=
{
   black = 0
   white = 0
   targetCopy = target.shallowCopy[]
   
   // First, count total number of matches in any position.  As a match is
   // found in any position, remove it from the list so it's not counted twice.
   for mpiece = combination
      if targetCopy.removeValue[mpiece]  // Returns true if a piece was removed
         white = white + 1

   // Now count pieces in the correct positions.  For each one found, remove
   // one from the "white" count and add one to the "black" count.
   for i = 0 to length[target]-1
      if combination@i == target@i
      {
         white = white - 1
         black = black + 1
      }

   return [black,white]
}



View or download CrackTheCode.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 18666 days, 0 hours, 54 minutes ago.