From ea78c765a6990aa47ecae3afa1b189047793afb9 Mon Sep 17 00:00:00 2001 From: Karl Ostmo Date: Mon, 7 Oct 2024 22:57:31 -0700 Subject: [PATCH] Better motivated puzzle --- data/scenarios/Challenges/_dna/solution.sw | 71 ++++++++++++++- data/scenarios/Challenges/_dna/topchecker.sw | 90 ++++++++++++++++++++ data/scenarios/Challenges/_dna/verifier.sw | 8 +- data/scenarios/Challenges/dna.yaml | 83 ++++++++++++++---- 4 files changed, 226 insertions(+), 26 deletions(-) create mode 100644 data/scenarios/Challenges/_dna/topchecker.sw diff --git a/data/scenarios/Challenges/_dna/solution.sw b/data/scenarios/Challenges/_dna/solution.sw index 5a384bdf5..76331ee86 100644 --- a/data/scenarios/Challenges/_dna/solution.sw +++ b/data/scenarios/Challenges/_dna/solution.sw @@ -1,5 +1,53 @@ def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end; +def getBaseForNumber = \n. + if (n == 0) { + "guanine"; + } { + if (n == 1) { + "cytosine"; + } { + if (n == 2) { + "adenine"; + } { + "thymine"; + }; + }; + }; + end; + +def getNumberForBase = \n. + if (n == "guanine") { + 0; + } { + if (n == "cytosine") { + 1; + } { + if (n == "adenine") { + 2; + } { + 3; + }; + }; + }; + end; + +def getComplementNumber = \n. + if (n == 0) { + 1; + } { + if (n == 1) { + 0; + } { + if (n == 2) { + 3; + } { + 2; + }; + }; + }; + end; + def waitWhileHere = \item. stillHere <- ishere item; if stillHere { @@ -24,12 +72,16 @@ def moveToPattern = turn right; doN 2 move; turn right; - doN 5 move; + doN 4 move; + turn right; + move; + turn left; + move; end; def moveToOtherRow = turn right; - doN 9 move; + doN 8 move; turn right; move; end; @@ -39,13 +91,22 @@ def waitForItem : Dir -> Cmd Text = \d. case item (\_. waitForItem d) return; end; + +def placeComplementOf = \item. + let baseNumber = getNumberForBase item in + let complementNumber = getComplementNumber baseNumber in + let newItem = getBaseForNumber complementNumber in + place newItem; + end; + /** Store the observed entities in the recursion stack. */ def replicatePattern = \standbyFunc. \n. if (n > 0) { - thingTemp <- waitForItem down; + thingTemp <- waitForItem left; let thing = thingTemp in + placeComplementOf thing; move; replicatePattern standbyFunc $ n - 1; @@ -58,9 +119,11 @@ def replicatePattern = \standbyFunc. \n. def go = move; - let sentinel = "flower" in place sentinel; + + doN 16 $ make "cytosine"; + waitWhileHere sentinel; moveToPattern; replicatePattern moveToOtherRow 32; diff --git a/data/scenarios/Challenges/_dna/topchecker.sw b/data/scenarios/Challenges/_dna/topchecker.sw new file mode 100644 index 000000000..86ddc1dc8 --- /dev/null +++ b/data/scenarios/Challenges/_dna/topchecker.sw @@ -0,0 +1,90 @@ +def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end; + +def getBaseForNumber = \n. + if (n == 0) { + "guanine"; + } { + if (n == 1) { + "cytosine"; + } { + if (n == 2) { + "adenine"; + } { + "thymine"; + }; + }; + }; + end; + +def getNumberForBase = \n. + if (n == "guanine") { + 0; + } { + if (n == "cytosine") { + 1; + } { + if (n == "adenine") { + 2; + } { + if (n == "thymine") { + 3; + } {-1}; + }; + }; + }; + end; + +def getComplementNumber = \n. + if (n == 0) { + 1; + } { + if (n == 1) { + 0; + } { + if (n == 2) { + 3; + } { + 2; + }; + }; + }; + end; + +def waitUntilHere = \remainingCount. + if (remainingCount > 0) { + maybeItemHere <- scan down; + case maybeItemHere (\_. + watch down; + wait 1000; + waitUntilHere remainingCount; + ) (\itemHere. + + maybeItemAbove <- scan left; + case maybeItemAbove (\_. fail "Expected an item here.") (\itemAbove. + let num = getNumberForBase itemAbove in + if (num >= 0) { + let complementNum = getComplementNumber num in + let complementItem = getBaseForNumber complementNum in + if (complementItem == itemHere) { + move; + waitUntilHere $ remainingCount - 1; + } { + create "pixel (R)"; + } + } { + fail "Expected nonnegative item index." + } + ); + ); + } { + log "Finished verifying top row"; + create "pixel (G)"; + }; + + end; + +def go = + instant $ waitUntilHere 32; + end; + +go; \ No newline at end of file diff --git a/data/scenarios/Challenges/_dna/verifier.sw b/data/scenarios/Challenges/_dna/verifier.sw index 4a58d3d05..ef11b9e20 100644 --- a/data/scenarios/Challenges/_dna/verifier.sw +++ b/data/scenarios/Challenges/_dna/verifier.sw @@ -162,22 +162,20 @@ def spawnComplementer = def makeDnaStrand = teleport self (5, -2); - r <- spawnComplementer; clonedOrganism <- placeBase myStandby 32; doN 3 move; drill forward; teleport self (36, -12); - give r "gold coin"; return clonedOrganism end; def go = instant $ waitUntilHere "flower"; - // _f <- grab; + create "pixel (G)"; clonedOrganism <- makeDnaStrand; - teleport self (40, -13); - place clonedOrganism; + // teleport self (40, -13); + // place clonedOrganism; end; go; \ No newline at end of file diff --git a/data/scenarios/Challenges/dna.yaml b/data/scenarios/Challenges/dna.yaml index feac3059d..2ebbe3cbc 100644 --- a/data/scenarios/Challenges/dna.yaml +++ b/data/scenarios/Challenges/dna.yaml @@ -14,17 +14,21 @@ objectives: condition: | r <- robotnamed "verifier"; as r { - has "flower"; + has "pixel (G)"; } - goal: - | You must complete the DNA strand with complementary base pairs. - - Pick up the result of the cloning experiment to win. condition: | - as base { - has "organic sludge"; + r <- robotnamed "topchecker"; + as r { + has "pixel (G)"; } + - goal: + - | + Pick up the result of the cloning experiment to win. + condition: | + return false; robots: - name: base dir: east @@ -34,28 +38,27 @@ robots: - branch predictor - comparator - dictionary + - feeler - switch puller - grabber - hearing aid - lambda - logger + - microscope - rolex - - scanner - strange loop - treads - welder - workbench inventory: - [1, flower] - - [64, guanine] - - [64, cytosine] - - [64, adenine] - - [64, thymine] + - [32, pipette] + - [16, primordial soup] - name: verifier system: true dir: east display: - invisible: true + invisible: false attr: 'robot' devices: - switch puller @@ -85,9 +88,47 @@ robots: - [1, solar panel] program: | run "data/scenarios/Challenges/_dna/verifier.sw" + - name: topchecker + system: true + dir: east + display: + invisible: false + attr: 'robot' + program: | + run "data/scenarios/Challenges/_dna/topchecker.sw" solution: | run "data/scenarios/Challenges/_dna/solution.sw" entities: + - name: primordial soup + display: + char: 's' + description: + - Can be decomposed into nucleic acids + properties: [known, pickable] + - name: feeler + display: + char: 'm' + description: + - Senses presense of specific entities + properties: [known, pickable] + capabilities: [blocked, ishere, isempty] + - name: microscope + display: + char: 'm' + description: + - Scan for the cost of 1 `pipette`{=entity} + properties: [known, pickable] + capabilities: + - capability: scan + cost: + - [1, "pipette"] + - name: pipette + display: + char: 'p' + attr: ice + description: + - One of the four nucleobases in DNA. + - Is paired with "cytosine". - name: guanine display: char: 'G' @@ -95,7 +136,7 @@ entities: description: - One of the four nucleobases in DNA. - Is paired with "cytosine". - properties: [pickable, known] + properties: [known] - name: cytosine display: char: 'C' @@ -103,7 +144,7 @@ entities: description: - One of the four nucleobases in DNA. - Is paired with "guanine". - properties: [pickable, known] + properties: [known] - name: adenine display: char: 'A' @@ -111,7 +152,7 @@ entities: description: - One of the four nucleobases in DNA. - Is paired with "thymine". - properties: [pickable, known] + properties: [known] - name: thymine display: char: 'T' @@ -119,7 +160,7 @@ entities: description: - One of the four nucleobases in DNA. - Is paired with "adenine". - properties: [pickable, known] + properties: [known] - name: switch (off) display: attr: red @@ -149,6 +190,13 @@ entities: description: - Can pull switches recipes: + - in: + - [1, primordial soup] + out: + - [4, cytosine] + - [4, guanine] + - [4, adenine] + - [4, thymine] - in: - [1, switch (off)] out: @@ -187,9 +235,10 @@ world: palette: '┬': [stone, down and horizontal wall] '┴': [stone, up and horizontal wall] + 'z': [stone, wall] '.': [stone, erase] ':': [blank, erase] - 'z': [stone, wall] + 'c': [blank, erase, topchecker] 'v': [stone, erase, verifier] 'B': [stone, erase, base] '0': [stone, switch (off)] @@ -199,7 +248,7 @@ world: z...........................................z z.....┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬......z z.....::::::::::::::::::::::::::::::::......z - z.zz..::::::::::::::::::::::::::::::::......z + z.zz..c:::::::::::::::::::::::::::::::......z zBvzzz┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴......z z.zz........................................z z...........................................z