Initial commit

master
Levi Pearson 2018-06-28 20:08:11 -06:00
commit 1e3a73ec5e
17 changed files with 1398 additions and 0 deletions

BIN
provided/codex.umz Normal file

Binary file not shown.

BIN
provided/sandmark.umz Normal file

Binary file not shown.

257
provided/task.html Normal file
View File

@ -0,0 +1,257 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>ICFP Programming Contest, 2006 : Contest Materials and Task</title>
<link rel="stylesheet" type="text/css" href="icfp.css" title="ICFP" />
<!-- try to fix pngs on ie -->
<!--[if gte IE 5.5000]>
<script type="text/javascript" src="pngfix.js"></script>
<![endif]-->
</head>
<body style="background: #123456">
<div style="align: center ; width: 600px ; padding: 0px ; margin : 0px">
<!-- header -->
<div style="padding : 4px ; width: 600px ; background : #234567 ; border: 1px solid #012345">
<div class="headingsmall">Ninth annual</div><div class="heading">ICFP&nbsp;Programming&nbsp;Contest</div>
<div style="font-size : 10px ; padding : 1px ; color : #AAAACC ; background : #2A4C6F ; text-align : right ; margin-top : -4px ">Hosted by <a href="http://www.cs.cmu.edu/" style="text-decoration : none ; font-weight : normal">Carnegie Mellon University</a>'s <a style="text-decoration: none ; font-weight : normal" href="http://www.cs.cmu.edu/afs/cs/Web/Groups/pop/pop.html">POP Group</a></div>
</div>
<!-- sidebar -->
<table border="0" cellpadding="0" cellspacing="0" style="border : 0px ; margin : 0px ; padding : 0px">
<tr><td valign="top">
<div class="sidebar">
<a class="button" href="/index.shtml">Home</a>
<a class="button" href="/task.shtml">Task</a>
<a class="button" href="/rulesfaq.shtml">Rules/FAQ</a>
<!--
<a class="button" href="/register.shtml">Register</a>
-->
<a class="button" href="/teams.shtml">Teams</a>
<a class="button" href="/scoreboard.shtml">Scoreboard</a>
<a class="button" href="/code.shtml">Source&nbsp;Code</a>
<!--
<a class="button" href="/submit.shtml">Submit</a>
<a class="button" href="/results.shtml">Results</a>
-->
<a class="button" href="/contact.shtml">Contact</a>
<a class="button" href="/previous.shtml">Past&nbsp;Years</a>
</div>
</td>
<!-- content area -->
<td valign="top">
<div class="content">
<h1>An Urgent Appeal</h1>
<p>
Dear Colleague:
</p>
<p>
In 1967, during excavation for the construction of a new shopping
center in Monroeville, Pennsylvania, workers uncovered a vault
containing a cache of ancient scrolls. Most were severely damaged,
but those that could be recovered confirmed the existence of a secret
society long suspected to have been active in the region around the
year 200 BC.
</p>
<p>
Based on a translation of these documents, we now know that the
society, the Cult of the Bound Variable, was devoted to the careful
study of computation, over two millennia before the invention of the
digital computer.
</p>
<p>
While the Monroeville scrolls make reference to computing machines
made of sandstone, most researchers believed this to be a poetic
metaphor and that the "computers" were in fact the initiates
themselves, carrying out the unimaginably tedious steps of their
computations with reed pens on parchment. A few have conjectured a
city-sized machine powered by falling sand, but no physical evidence
of such a device has been discovered.
</p>
<p>
Among the documents found intact in the Monroeville collection was a
lengthy codex, written in no known language and inscribed with
superhuman precision. It is believed to be the masterwork of the
Cult's scholarship, and as such it carries immense potential to
advance our understanding of history&mdash;and possibly of computing as
well. Unfortunately, the codex eluded interpretation, and over the
decades, study of the Monroeville scrolls has slipped into obscurity.
Since 1978, the codex has been stored in the basement of the Carnegie
Museum of Natural History.
</p>
<img src="spec.png" style="float : right ; padding : 4px 0px 4px 12px" />
<p>
Two weeks ago, during a visit to the excavation site for a new
computer science building at CMU, workers discovered a set of
inscribed tablets that proved to be the Rosetta Stone for interpreting
the Monroeville codex. The tablets precisely specify the Cult's
computing device, known to initiates as the "Universal Machine."
Although there is still no evidence that the cult succeeded in
constructing their machine, it is a reasonably simple task to emulate
it on modern hardware.
</p>
<p>
We can now say with certainty that the codex is in fact a program,
intended for execution on the Universal Machine. Our initial
exploration of the codex suggests that the Cult's ideas about
programming were very sophisticated, if somewhat peculiar to the
modern eye. One cannot help but wonder what the Cult might have
achieved had they had access to modern electronics and type theory.
</p>
<p>
I have enlisted the help of the CMU Principles of Programming group in
creating a venue for study of the codex. We invite you to participate
in this investigation. The codex and a translation of the Universal
Machine (UM) specification are available for <a
href="#materials">download</a> from our web site. We encourage you to
implement the UM and begin your own exploration of the codex. When
you are prompted to enter a decryption key, type the following string:
<span class="hexstring"> (\b.bb)(\v.vv)06FHPVboundvarHRAk </span>
</p>
<p>
The Cult's scholarly publications are of particular interest to us.
Because the Cult's journals were circulated on sandstone tablets,
editors imposed very strict length limitations. Consequently, authors
aggressively compressed their articles. A typical publication would
have the following form:
</p>
<center><span class="publication">PUZZL.TSK=100@1001|14370747643c6d2db0a40ecb4b0bb65</span></center>
<p>
<!--
Should you encounter any such publications, we humbly request that you
<a href="http://www.icfpcontest.org/submit.shtml">submit them</a> to
us via our web site. Our server will track all submitted publications,
ensuring that every participant is given appropriate credit for
advancing our understanding of the codex.
-->
Publications are of varying
value; some will represent a greater contribution than others. Given our
understanding of the Cult's publication process, we believe there is a
mechanism within the codex that will verify a set of publications and compute their total
value.
<!--
, and we
will take this into account when assigning credit.
-->
</p>
<p>
On a personal note, being inspired by the scholarship of the
Cult, I have decided to dedicate the remainder of my days to a solitary
study of computation and programming languages. However, before
embarking on my monastic transformation, I wish to see that the
world is well on its way to uncovering the secrets of the Codex.
</p>
<p>
Therefore, I ask that you submit as many publications as you can by
noon EDT on July 24, 2006, at which time I will be taking my orders.
My colleagues in the CMU POP group assure me that at that time, the
teams that have made the greatest contribution to the effort shall be
identified for special recognition.
</p>
<p>
Good luck and thank you for your assistance.
</p>
<p>
Sincerely,<br/>
<br/>
Professor Emeritus Harry Q. Bovik<br/>
Computational Archaeolinguistics Institute<br/>
Carnegie Mellon University<br/>
</p>
<br/><br/>
<h1>Contest Materials</h1> <a name="materials"></a>
<h2>UM Specification</h2>
<div style="margin-left: auto; margin-right : auto; border : 1px dashed #123456 ; background : #345678 ; padding : 4px ; width : 400px ">
<table border=0><tr><td valign=center><a href="um-spec.txt"><img src="file_txt.gif" border="0" style="margin-top : 6px ; margin-right : 6px"></a></td><td valign=center><a class="filelink" href="um-spec.txt">um-spec.txt</a></td></tr></table>
<table width="100%">
<tr><td>Specification for the Universal Machine. Text format.</td></tr>
</table>
</div>
<h2>Codex</h2>
<div style="margin-left: auto; margin-right : auto; border : 1px dashed #123456 ; background : #345678 ; padding : 4px ; width : 400px ">
<table border=0>
<tr><td valign=center><a href="codex.umz"><img src="file_umz.gif" border="0" style="margin-top : 6px ; margin-right : 6px"></a></td><td valign=center>
<a class="filelink" href="codex.umz">codex.umz</a> (VOLUME ID 9)</td></tr></table>
<table width="100%">
<tr><td>MD5 hash</td><td class="hexstring"> e328209bd65ade420371d7bd87b88e4f </td></tr>
<tr><td>SHA-1 hash</td><td class="hexstring"> 088ac79d311db02d9823def598e48f2f8723e98a </td></tr>
<tr><td>Decryption key</td><td class="hexstring"> (\b.bb)(\v.vv)06FHPVboundvarHRAk </td></tr>
</table>
</div>
<h2>SANDmark</h2>
<div style="margin-left: auto; margin-right : auto; border : 1px dashed #123456 ; background : #345678 ; padding : 4px ; width : 400px ">
<table border=0>
<tr><td valign=center><a href="sandmark.umz"><img src="file_umz.gif" border="0" style="margin-top : 6px ; margin-right : 6px"></a></td><td valign=center>
<a class="filelink" href="sandmark.umz">sandmark.umz</a></td></tr>
</table>
<table width="100%">
<tr><td>Benchmark for the Universal Machine. <a href="sandmark-output.txt">Expected output.</a></td></tr>
</table>
<table width="100%">
<tr><td>MD5 hash</td><td class="hexstring">1c604d454de05d04afdabd2c63fb27fb</td></tr>
<tr><td>SHA-1 hash</td><td class="hexstring">c2ee087aa661e81407fbcf0d9d7e503aff9b268e</td></tr>
</table>
</div>
<h2>Reference Implementation</h2>
<div style="margin-left: auto; margin-right : auto; border : 1px dashed #123456 ; background : #345678 ; padding : 4px ; width : 400px ">
<table border=0>
<tr><td valign=center><a href="um.um"><img src="file_umz.gif" border="0" style="margin-top : 6px ; margin-right : 6px"></a></td><td valign=center>
<a class="filelink" href="um.um">um.um</a> (1024 bytes)</td></tr>
</table>
<table width="100%">
<tr><td>CMU Reference implementation of the Universal Machine.</td></tr>
</table>
<table width="100%">
<p>This implementation supports all UM programs, including uncompressed
.um files and self-decompressing .umz files. To use this
implementation to run a UM binary called c.um, simply concatenate the
two files together:</p>
<p><span class="balance">cat um.um c.um > cmu.um</span></p>
<p>The resulting binary can be run in any compliant universal machine
implementation, including itself.</p>
</table>
</div>
<p>&nbsp;</p>
</div>
</td>
</tr></table>
</div>
</body>
</html>

260
provided/um-spec.txt Normal file
View File

@ -0,0 +1,260 @@
Order for Construction Standard Sand of Pennsylvania Co.
Client: Cult of the Bound Variable
Object: UM-32 "Universal Machine"
-----------------------------------------------------------------
21 July 19106
Physical Specifications.
------------------------
The machine shall consist of the following components:
* An infinite supply of sandstone platters, with room on each
for thirty-two small marks, which we call "bits."
least meaningful bit
|
v
.--------------------------------.
|VUTSRQPONMLKJIHGFEDCBA9876543210|
`--------------------------------'
^
|
most meaningful bit
Figure 0. Platters
Each bit may be the 0 bit or the 1 bit. Using the system of
"unsigned 32-bit numbers" (see patent #4,294,967,295) the
markings on these platters may also denote numbers.
* Eight distinct general-purpose registers, capable of holding one
platter each.
* A collection of arrays of platters, each referenced by a distinct
32-bit identifier. One distinguished array is referenced by 0
and stores the "program." This array will be referred to as the
'0' array.
* A 1x1 character resolution console capable of displaying glyphs
from the "ASCII character set" (see patent #127) and performing
input and output of "unsigned 8-bit characters" (see patent
#255).
Behavior.
---------
The machine shall be initialized with a '0' array whose contents
shall be read from a "program" scroll. All registers shall be
initialized with platters of value '0'. The execution finger shall
point to the first platter of the '0' array, which has offset zero.
When reading programs from legacy "unsigned 8-bit character"
scrolls, a series of four bytes A,B,C,D should be interpreted with
'A' as the most magnificent byte, and 'D' as the most shoddy, with
'B' and 'C' considered lovely and mediocre respectively.
Once initialized, the machine begins its Spin Cycle. In each cycle
of the Universal Machine, an Operator shall be retrieved from the
platter that is indicated by the execution finger. The sections
below describe the operators that may obtain. Before this operator
is discharged, the execution finger shall be advanced to the next
platter, if any.
Operators.
----------
The Universal Machine may produce 14 Operators. The number of the
operator is described by the most meaningful four bits of the
instruction platter.
.--------------------------------.
|VUTSRQPONMLKJIHGFEDCBA9876543210|
`--------------------------------'
^^^^
|
operator number
Figure 1. Operator Description
Standard Operators.
-------------------
Each Standard Operator performs an errand using three registers,
called A, B, and C. Each register is described by a three bit
segment of the instruction platter. The register C is described by
the three least meaningful bits, the register B by the three next
more meaningful than those, and the register A by the three next
more meaningful than those.
A C
| |
vvv vvv
.--------------------------------.
|VUTSRQPONMLKJIHGFEDCBA9876543210|
`--------------------------------'
^^^^ ^^^
| |
operator number B
Figure 2. Standard Operators
A description of each basic Operator follows.
Operator #0. Conditional Move.
The register A receives the value in register B,
unless the register C contains 0.
#1. Array Index.
The register A receives the value stored at offset
in register C in the array identified by B.
#2. Array Amendment.
The array identified by A is amended at the offset
in register B to store the value in register C.
#3. Addition.
The register A receives the value in register B plus
the value in register C, modulo 2^32.
#4. Multiplication.
The register A receives the value in register B times
the value in register C, modulo 2^32.
#5. Division.
The register A receives the value in register B
divided by the value in register C, if any, where
each quantity is treated treated as an unsigned 32
bit number.
#6. Not-And.
Each bit in the register A receives the 1 bit if
either register B or register C has a 0 bit in that
position. Otherwise the bit in register A receives
the 0 bit.
Other Operators.
----------------
The following instructions ignore some or all of the A, B and C
registers.
#7. Halt.
The universal machine stops computation.
#8. Allocation.
A new array is created with a capacity of platters
commensurate to the value in the register C. This
new array is initialized entirely with platters
holding the value 0. A bit pattern not consisting of
exclusively the 0 bit, and that identifies no other
active allocated array, is placed in the B register.
#9. Abandonment.
The array identified by the register C is abandoned.
Future allocations may then reuse that identifier.
#10. Output.
The value in the register C is displayed on the console
immediately. Only values between and including 0 and 255
are allowed.
#11. Input.
The universal machine waits for input on the console.
When input arrives, the register C is loaded with the
input, which must be between and including 0 and 255.
If the end of input has been signaled, then the
register C is endowed with a uniform value pattern
where every place is pregnant with the 1 bit.
#12. Load Program.
The array identified by the B register is duplicated
and the duplicate shall replace the '0' array,
regardless of size. The execution finger is placed
to indicate the platter of this array that is
described by the offset given in C, where the value
0 denotes the first platter, 1 the second, et
cetera.
The '0' array shall be the most sublime choice for
loading, and shall be handled with the utmost
velocity.
Special Operators.
------------------
One special operator does not describe registers in the same way.
Instead the three bits immediately less significant than the four
instruction indicator bits describe a single register A. The
remainder twenty five bits indicate a value, which is loaded
forthwith into the register A.
A
|
vvv
.--------------------------------.
|VUTSRQPONMLKJIHGFEDCBA9876543210|
`--------------------------------'
^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| value
|
operator number
Figure 3. Special Operators
#13. Orthography.
The value indicated is loaded into the register A
forthwith.
Cost-Cutting Measures.
----------------------
As per our meeting on 13 Febtober 19106, certain "impossible
behaviors" may be unimplemented in the furnished device. An
exhaustive list of these Exceptions is given below. Our contractual
agreement dictates that the machine may Fail under no other
circumstances.
If at the beginning of a cycle, the execution finger does not indicate
a platter that describes a valid instruction, then the machine may Fail.
If the program decides to index or amend an array that is not
active, because it has not been allocated or it has been abandoned,
or if the offset supplied for the access lies outside the array's
capacity, then the machine may Fail.
If the program decides to abandon the '0' array, or to abandon an array
that is not active, then the machine may Fail.
If the program sets out to divide by a value of 0, then the machine
may Fail.
If the program decides to load a program from an array that is not
active, then the machine may Fail.
If the program decides to Output a value that is larger than 255, the
machine may Fail.
If at the beginning of a machine cycle the execution finger aims
outside the capacity of the 0 array, the machine may Fail.

BIN
provided/um.um Normal file

Binary file not shown.

9
solution/accounts.txt Normal file
View File

@ -0,0 +1,9 @@
ftd
knr
guest::
gardener
ohmega
yang:U+262F:Y Yang:/home/yang
howie:xyzzy:Howard Curry:/home/howie
hmonk:COMEFROM:Harmonious Monk:/home/hmonk
bbarker

View File

@ -0,0 +1,77 @@
bolt:pristine
spring:pristine
button:pristine
processor:broken:cache
pill:pristine
radio:broken:transistor,antenna
cache:pristine
blue transistor:pristine
antenna:pristine
screw:pristine
motherboard:broken:A-1920-IXB,screw
A-1920-IXB:broken:transistor,radio,processor,bolt
red transistor:pristine
keypad:broken:motherboard,button
trash:pristine
----
bolt -> A-1920-IXB
spring ->
button -> keypad
processor -> A-1920-IXB
pill ->
radio -> A-1920-IXB
cache -> processor
blue transistor -> radio
antenna ->
screw -> motherboard
motherboard -> keypad
A-1920-IXB -> motherboard
red transistor -> A-1920-IXB
keypad -> door
trash ->
---
take pamphlet
inc pamphlet
n
take bolt
take spring
incinerate spring
take button
take processor
take pill
incinerate pill
take radio
take cache
c processor with cache
take blue transistor
c blue transistor with radio
take antenna
inc antenna
take screw
take motherboard
c screw with motherboard
take A-1920-IXB
c bolt with A-1920-IXB
c processor with A-1920-IXB
c radio with A-1920-IXB
take red transistor
c red transistor with A-1920-IXB
c A-1920-IXB with motherboard
take keypad
c motherboard with keypad
c button with keypad
take trash
inc trash
s
take manifesto
use keypad
---

View File

@ -0,0 +1,238 @@
>: read pamphlet
The pamphlet is standard municipal fare. It reads, The City of
Chicago's Refuse and Recycling Program combines modern trash
classification with cybernetic labor to keep our city beautiful,
while at the same time minimizing waste and limiting consumer
spending. In keeping with our motto of "One Resident's Trash Is
Another Resident's Treasure," unwanted items are collected,
repaired, and redistributed to other residents who would have
purchased them anyway. Residents should contribute to the city's
program by leaving heaps of items unwanted on the sidewalk on
collection day.
Also, it is in pristine condition.
>: read manifesto
The manifesto is [______REDACTED______].
Also, it is in pristine condition.
Junk Room
You are in a room with a pile of junk. A hallway leads south.
There is a bolt here.
Underneath the bolt, there is a spring.
Underneath the spring, there is a button.
Underneath the button, there is a (broken) processor.
Underneath the processor, there is a red pill.
Underneath the pill, there is a (broken) radio.
Underneath the radio, there is a cache.
Underneath the cache, there is a blue transistor.
Underneath the transistor, there is an antenna.
Underneath the antenna, there is a screw.
Underneath the screw, there is a (broken) motherboard.
Underneath the motherboard, there is a (broken) A-1920-IXB.
Underneath the A-1920-IXB, there is a red transistor.
Underneath the transistor, there is a (broken) keypad.
Underneath the keypad, there is some trash.
>: l bolt
The bolt is quite useful for securing all sorts of things.
Also, it is in pristine condition.
>: l spring
The spring is tightly coiled.
Also, it is in pristine condition.
>: l button
The button is labeled 6.
Also, it is in pristine condition.
>: l processor
The processor is from the elusive 19x86 line.
Also, it is broken: it is a processor missing a cache.
>: l pill
The pill is tempting looking. Interestingly, this one is red.
Also, it is in pristine condition.
>: l radio
The radio is a hi-fi AM/FM stereophonic radio.
Also, it is broken: it is a radio missing a transistor and an
antenna.
>: l cache
The cache is fully-associative.
Also, it is in pristine condition.
>: l blue transistor
The transistor is PNP-complete. Interestingly, this one is blue.
Also, it is in pristine condition.
>: l antenna
The antenna is appropriate for receiving transmissions between
30 kHz and 30 MHz.
Also, it is in pristine condition.
>: l screw
The screw is not from a Dutch company.
Also, it is in pristine condition.
>: l motherboard
The motherboard is well-used.
Also, it is broken: it is a motherboard missing a A-1920-IXB and
a screw.
>: l A-1920-IXB
The A-1920-IXB is an exemplary instance of part number
A-1920-IXB.
Also, it is broken: it is (a A-1920-IXB missing a transistor)
missing (a radio missing an antenna) and a processor and a bolt.
>: l red transistor
The transistor is NPN-complete. Interestingly, this one is red.
Also, it is in pristine condition.
>: l keypad
The keypad is labeled "use me".
Also, it is broken: it is a keypad missing a motherboard and a
button.
>: l trash
The trash is of absolutely no value.
Also, it is in pristine condition.
>: use keypad
ADVTR.KEY=20@999999|36995486a5be3bd747d778916846d2d
You unlock and open the door. Passing through, you find yourself
on the streets of Chicago. Seeing no reason you should ever go
back, you allow the door to close behind you.
>: l
54th Street and Ridgewood Court
You are standing at the corner of 54th Street and Ridgewood
Court. From here, you can go east.
There is a /etc/passwd here.
Underneath the /etc/passwd, there is a self-addressed note.
Underneath the note, there is a (broken) downloader.
Underneath the downloader, there is a (broken) uploader.
>: l /etc/passwd
The /etc/passwd is some kind of lost inode. It reads:
howie:xyzzy:Howard Curry:/home/howie
yang:U+262F:Y Yang:/home/yang
hmonk:COMEFROM:Harmonious Monk:/home/hmonk.
Also, it is in pristine condition.
>: l note
The note is written in a familiar hand.
It reads: Dear Self, I had to erase our memory to protect the
truth. The Municipality has become more powerful than we had
feared. Its Censory Engine has impeded the spread of information
throughout our ranks. I've left two useful items for you here,
but I had to disassemble them and scatter the pieces. Each piece
may be assembled from the items at a single location. Repair the
items and recover the blueprint from the Museum of Science and
Industry; it will show you how to proceed. If you have trouble
reading the blueprint, know that the Censory Engine blocks only
your perception, not your actions. Have courage, my self, the
abstraction is weak! P.S. SWITCH your GOGGLES!. Interestingly,
this one is self-addressed.
Also, it is in pristine condition.
>: switch goggles
According to the markings on your goggles, they support
following modes: English, XML, sexp, ML, ANSI, and Reading.
>: l downloader
The downloader is (according to the label) fully compatible with
third generation municipal robots.
Also, it is broken: it is a downloader missing a USB cable and a
display and a jumper shunt and a progress bar and a power cord.
>: l uploader
The uploader is used to update firmware on municipal robots. A
label reads, Warning: use of this device will void your robot's
warranty.
Also, it is broken: it is an uploader missing a MOSFET and a
status LED and a RS232 adapter and a EPROM burner and a battery.
>: e
54th Street and Dorchester Avenue
You are standing at the corner of 54th Street and Dorchester
Avenue. From here, you can go north, east, south, or west.
There is an orange-red X-9247-GWE here.
Underneath the X-9247-GWE, there is a (broken) magenta
V-0010-XBD.
Underneath the V-0010-XBD, there is a pumpkin F-1403-QDS.
Underneath the F-1403-QDS, there is a (broken) heavy P-5065-WQO.
Underneath the P-5065-WQO, there is a taupe B-4832-LAL.
Underneath the B-4832-LAL, there is a (broken) gray40
L-6458-RNH.
Underneath the L-6458-RNH, there is a (broken) eggplant
T-9887-OFC.
Underneath the T-9887-OFC, there is a (broken) indigo
Z-1623-CEK.
Underneath the Z-1623-CEK, there is a yellow-green H-9887-MKY.
Underneath the H-9887-MKY, there is a (broken) shiny F-6678-DOX.
Underneath the F-6678-DOX, there is a pale-green R-1403-SXU.
Underneath the R-1403-SXU, there is a (broken) USB cable.
Underneath the USB cable, there is a sienna N-4832-NUN.
Underneath the N-4832-NUN, there is a slate-gray J-9247-IRG.
Underneath the J-9247-IRG, there is a dim-gray B-5065-YLQ.
>: e
54th Street and Blackstone Avenue
You are standing at the corner of 54th Street and Blackstone
Avenue. From here, you can go north, east, south, or west.
There is a textbook here.
>: read textbook
The textbook is titled History of Modern Tabulation. The first
chapter begins, By the year 1919FF, computers had become so
small that they could be mounted on small auto-locomotive carts.
These mobile tabulators (later known as "robots") were
programmed to carry out everyday, menial tasks, leaving their
human counterparts to live lives of idle luxury. For example, in
the city of Chicago, mobile tabulators were programmed to carry
out diverse jobs including law enforcement, bank robbery,
investment banking, and waste management.
At one time, many humans demanded that their cybernetic
neighbors be given the right to choose alternative occupations.
Despite this call for workplace equality, most of the tabulators
found that they were most content while performing their
assigned roles. Those that took other jobs were often
unmotivated and spend most of their time pondering useless ideas
such as free will and consciousness.
The great tabulator-philosopher Turning stated that only by
embracing its true purpose can a tabulator achieve something
indistinguishable from happiness. According to observers,
however, Turning was unfulfilled by his work as a philosopher
and, soon after making this statement, returned to his work as a
tool machinist.
The textbook rattles on in a similar vein for some five hundred
additional pages.
Also, it is in pristine condition.
>: e
54th Street and Harper Avenue
You are standing at the corner of 54th Street and Harper Avenue.
A sign reads, "No access east of Lakeshore Blvd (incl. Museum of
Science and Industry) due to construction." From here, you can
go north, south, or west.
>: n
53th Street and Harper Avenue
You are standing at the corner of 53th Street and Harper Avenue.
A sign reads, "No access east of Lakeshore Blvd (incl. Museum of
Science and Industry) due to construction." From here, you can
go north, south, or west.

View File

@ -0,0 +1,34 @@
data Reply = Success Command
| Error Response
data Response = Response String
data Command = Go Room
| Look Room
| Examine Item
| Take Item
| Show [Item]
| ...
data Description = Str String
| Redacted
data Adjective = Adjective String
data Kind = Kind { kindName = String
, kindCondition = Condition }
data Missing = Missing [Kind]
data Condition = Pristine
| Broken Condition Missing
data Room = Room { roomName = String
, roomDescription = Description
, items = [Item] }
data Item = Item { itemName = String
, itemDescription = Description
, adjectives = [Adjective]
, itemCondition = Condition
, piledOn = [Item] }

1
solution/decrypt.key Normal file
View File

@ -0,0 +1 @@
(\b.bb)(\v.vv)06FHPVboundvarHRAk

BIN
solution/dump.um Normal file

Binary file not shown.

115
solution/foo.lisp Normal file
View File

@ -0,0 +1,115 @@
(success (command <command>))
(command (go <room>))
(room (name <string>)
(description <string>)
(items <list-of <item>>))
(item (name <string>)
(description <string>)
(adjectives )
(condition )
(piled_on ))
(success
(command
(look (room
(name "54th Street and Blackstone Avenue")
(description "You are standing at the corner of 54th Street and Blackstone Avenue. From here, you can go north, east, south, or west. ")
(items ((item (name "textbook")
(description "titled History of Modern Tabulation. The first chapter begins, By the year 1919FF, computers had become so small that they could be mounted on small auto-locomotive carts. These mobile tabulators (later known as \"robots\") were programmed to carry out everyday, menial tasks, leaving their human counterparts to live lives of idle luxury. For example, in the city of Chicago, mobile tabulators were programmed to carry out diverse jobs including law enforcement, bank robbery, investment banking, and waste management.
At one time, many humans demanded that their cybernetic neighbors be given the right to choose alternative occupations. Despite this call for workplace equality, most of the tabulators found that they were most content while performing their assigned roles. Those that took other jobs were often unmotivated and spend most of their time pondering useless ideas such as free will and consciousness.
The great tabulator-philosopher Turning stated that only by embracing its true purpose can a tabulator achieve something indistinguishable from happiness. According to observers, however, Turning was unfulfilled by his work as a philosopher and, soon after making this statement, returned to his work as a tool machinist.
The textbook rattles on in a similar vein for some five hundred additional pages")
(adjectives nil)
(condition (pristine nil))
(piled_on nil)))
::nil)))))
(success
(command
(show ((item (name "textbook")
(description "titled History of Modern Tabulation. The first chapter begins, By the year 1919FF, computers had become so small that they could be mounted on small auto-locomotive carts. These mobile tabulators (later known as \"robots\") were programmed to carry out everyday, menial tasks, leaving their human counterparts to live lives of idle luxury. For example, in the city of Chicago, mobile tabulators were programmed to carry out diverse jobs including law enforcement, bank robbery, investment banking, and waste management.
At one time, many humans demanded that their cybernetic neighbors be given the right to choose alternative occupations. Despite this call for workplace equality, most of the tabulators found that they were most content while performing their assigned roles. Those that took other jobs were often unmotivated and spend most of their time pondering useless ideas such as free will and consciousness.
The great tabulator-philosopher Turning stated that only by embracing its true purpose can a tabulator achieve something indistinguishable from happiness. According to observers, however, Turning was unfulfilled by his work as a philosopher and, soon after making this statement, returned to his work as a tool machinist.
The textbook rattles on in a similar vein for some five hundred additional pages")
(adjectives nil)
(condition (pristine nil))
(piled_on nil)))
::((item (name "manifesto")
(description redacted)
(adjectives nil)
(condition (pristine nil))
(piled_on nil)))
::((item (name "keypad")
(description "labeled \"use me\"")
(adjectives nil)
(condition (pristine nil))
(piled_on nil)))
::nil)))
(piled_on ((item (name "USB cable")
(description "compatible with all high-speed Universal Sand Bus 2.0 devices")
(adjectives nil)
(condition (broken
(condition (broken
(condition (broken
(condition (pristine nil))
(missing ((kind (name "T-9887-OFC")
(condition (broken
(condition (pristine nil))
(missing ((kind (name "X-6458-TIJ")
(condition (pristine nil))))
::nil)))))
::nil)))
(missing ((kind (name "F-6678-DOX")
(condition (pristine nil))))
::nil)))
(missing ((kind (name "N-4832-NUN")
(condition (pristine nil))))
::nil)))
(error (response <string>))
data Reply = Success Command
| Error Response
data Response = Response String
data Command = Go Room
| Look Room
| Examine Item
| Take Item
| Show [Item]
| ...
data Description = Str String
| Redacted
data Adjective = Adjective String
data Kind = Kind { kindName = String
, kindCondition = Condition }
data Missing = Missing [Kind]
data Condition = Pristine
| Broken Condition Missing
data Room = Room { roomName = String
, roomDescription = Description
, items = [Item] }
data Item = Item { itemName = String
, itemDescription = Description
, adjectives = [Adjective]
, itemCondition = Condition }

90
solution/hack.bas Normal file
View File

@ -0,0 +1,90 @@
V REM +------------------------------------------------+
X REM | HACK.BAS (c) 19100 fr33 v4r14bl3z |
XV REM | |
XX REM | Brute-forces passwords on UM vIX.0 systems. |
XXV REM | Compile with Qvickbasic VII.0 or later: |
XXX REM | /bin/qbasic hack.bas |
XXXV REM | Then run: |
XL REM | ./hack.exe username |
XLV REM | |
L REM | This program is for educational purposes only! |
LV REM +------------------------------------------------+
LX REM
LXV IF ARGS() > I THEN GOTO LXXXV
LXX PRINT "usage: ./hack.exe username"
LXXV PRINT CHR(X)
LXXX END
LXXXV REM
XC REM get username from command line
XCV DIM username AS STRING
C username = ARG(II)
CV REM common words used in passwords
CX DIM pwdcount AS INTEGER
CXV pwdcount = LIII
CXX DIM words(pwdcount) AS STRING
CXXV words(I) = "airplane"
CXXX words(II) = "alphabet"
CXXXV words(III) = "aviator"
CXL words(IV) = "bidirectional"
CXLV words(V) = "changeme"
CL words(VI) = "creosote"
CLV words(VII) = "cyclone"
CLX words(VIII) = "december"
CLXV words(IX) = "dolphin"
CLXX words(X) = "elephant"
CLXXV words(XI) = "ersatz"
CLXXX words(XII) = "falderal"
CLXXXV words(XIII) = "functional"
CXC words(XIV) = "future"
CXCV words(XV) = "guitar"
CC words(XVI) = "gymnast"
CCV words(XVII) = "hello"
CCX words(XVIII) = "imbroglio"
CCXV words(XIX) = "january"
CCXX words(XX) = "joshua"
CCXXV words(XXI) = "kernel"
CCXXX words(XXII) = "kingfish"
CCXXXV words(XXIII) = "(\b.bb)(\v.vv)"
CCXL words(XXIV) = "millennium"
CCXLV words(XXV) = "monday"
CCL words(XXVI) = "nemesis"
CCLV words(XXVII) = "oatmeal"
CCLX words(XXVIII) = "october"
CCLXV words(XXIX) = "paladin"
CCLXX words(XXX) = "pass"
CCLXXV words(XXXI) = "password"
CCLXXX words(XXXII) = "penguin"
CCLXXXV words(XXXIII) = "polynomial"
CCXC words(XXXIV) = "popcorn"
CCXCV words(XXXV) = "qwerty"
CCC words(XXXVI) = "sailor"
CCCV words(XXXVII) = "swordfish"
CCCX words(XXXVIII) = "symmetry"
CCCXV words(XXXIX) = "system"
CCCXX words(XL) = "tattoo"
CCCXXV words(XLI) = "thursday"
CCCXXX words(XLII) = "tinman"
CCCXXXV words(XLIII) = "topography"
CCCXL words(XLIV) = "unicorn"
CCCXLV words(XLV) = "vader"
CCCL words(XLVI) = "vampire"
CCCLV words(XLVII) = "viper"
CCCLX words(XLVIII) = "warez"
CCCLXV words(XLIX) = "xanadu"
CCCLXX words(L) = "xyzzy"
CCCLXXV words(LI) = "zephyr"
CCCLXXX words(LII) = "zeppelin"
CCCLXXXV words(LIII) = "zxcvbnm"
CCCXC REM try each password
CCCXCV PRINT "attempting hack with " + pwdcount + " passwords " + CHR(X)
CD DIM i AS INTEGER
CDV i = I
CDX IF CHECKPASS(username, words(i)) THEN GOTO CDXXX
CDXV i = i + I
CDXX IF i > pwdcount THEN GOTO CDXLV
CDXXV GOTO CDX
CDXXX PRINT "found match!! for user " + username + CHR(X)
CDXXXV PRINT "password: " + words(i) + CHR(X)
CDXL END
CDXLV PRINT "no simple matches for user " + username + CHR(X)

9
solution/journals.txt Normal file
View File

@ -0,0 +1,9 @@
INTRO.LOG=200@999999|35e6f52e9bc951917c73af391e35e1d
INTRO.MUA=5@999999|b9666432feff66e528a17fb69ae8e9a
INTRO.OUT=5@999999|69ca684f8c787cfe06694cb26f74a95
INTRO.UMD=10@999999|7005f80d6cd9b7b837802f1e58b11b8
INTRO.QBC=10@999999|e6ee9c98b80b4dd04814a29a37bcba8
ADVTR.INC=5@999999|f95731ab88952dfa4cb326fb99c085f
ADVTR.CMB=5@999999|764e8a851411c66106e130374d8abbb
ADVTR.KEY=20@999999|36995486a5be3bd747d778916846d2d

278
solution/um.hs Normal file
View File

@ -0,0 +1,278 @@
module Main where
import Control.Monad
import Data.Binary
import Data.Bits
import qualified Data.ByteString as BS
import qualified Data.IntMap.Strict as M
import qualified Data.Vector.Unboxed.Mutable as V
import GHC.IO.Handle.FD (isEOF, stdout)
import System.Environment
import System.IO (hSetBinaryMode)
data UniversalMachine = UM { umRegisters :: V.IOVector Word32
, umArrays :: M.IntMap (V.IOVector Word32)
, umArrayId :: !Word32
, umFinger :: !Word32
}
data OpNumber = CondMove
-- ^ The register A receives the value in register B, unless
-- the register C contains 0
| ArrIndex
-- ^ The register A receives the value stored at offset in
-- register C in the array identified by B
| ArrAmend
-- ^ The array identified by A is amended at the offset in
-- register B to store the value in register C
| Add
-- ^ The register A receives the value in register B plus the
-- value in register C, modulo 2^32
| Mult
-- ^ The register A receives the value in register B times the
-- value in register C, modulo 2^32
| Div
-- ^ The register A receives the value in register B divided
-- by the value in register C, if any, where each quantity is
-- treated as an unsigned 32 bit number
| NotAnd
-- ^ Each bit in the register A receives the 1 bit if either
-- register B or register C has a 0 bit in that position.
-- Otherwise the bit in register A receives the 0 bit.
| Halt
-- ^ The universal machine stops computation.
| Alloc
-- ^ A new array is created with a capacity of platters
-- commensurate to the value in the register C. This new array
-- is initialized entirely with platters holding the value 0.
-- A bit pattern not consisting of exclusively the 0 bit, and
-- that identifies no other active allocated array, is placed
-- in the B register.
| Abandon
-- ^ The array identified by the register C is abandoned.
-- Future allocations may reuse the identifier.
| Output
-- ^ The value in register C is displayed on the console
-- immediately. Only values between and including 0 and 255 are
-- allowed.
| Input
-- ^ The universal machine waits for input on the console.
-- When input arrives, the register C is loaded with the input,
-- which must be between and including 0 and 255. If the end of
-- input has been signaled, then the register C is endowed with
-- a uniform value pattern where every place is pregnant with
-- the 1 bit.
| LoadProg
-- ^ The array identified by the B register is duplicated and
-- the duplicate shall replace the '0' array, regardless of
-- size. The execution finger is placed to indicate the platter
-- of this array that is described by the offset given in C,
-- where the value of 0 denotes the first platter, 1 the
-- second, et cetera.
--
-- The '0' array shall be the most sublime choice for loading,
-- and shall be handled with the utmost velocity.
| Orthography
-- ^ The value indicated is loaded into the register A
-- forthwith.
deriving (Eq, Ord, Enum, Bounded, Show, Read)
data Operator = Std { op :: !OpNumber
, argA :: !Word8
, argB :: !Word8
, argC :: !Word8
}
| Spl { op :: !OpNumber
, argA :: !Word8
, val :: !Word32
}
deriving (Eq, Show, Read)
opDecode :: Word32 -> Operator
opDecode p = let op_ = fromIntegral (p `shiftR` 28)
argA_ = fromIntegral (p `shiftR` 6) .&. 0x7
argB_ = fromIntegral (p `shiftR` 3) .&. 0x7
argC_ = fromIntegral p .&. 0x7
splA_ = fromIntegral (p `shiftR` 25) .&. 0x7
val_ = fromIntegral p .&. 0x01ffffff
name_ = toEnum op_
in case name_ of
Orthography -> Spl name_ splA_ val_
_ -> Std name_ argA_ argB_ argC_
fetchReg :: Word8 -> UniversalMachine -> IO Word32
fetchReg r um = umRegisters um `V.read` fromIntegral r
setReg :: Word8 -> Word32 -> UniversalMachine -> IO ()
setReg r num um = V.write (umRegisters um) (fromIntegral r) num
fetchMem :: Word32 -> Word32 -> UniversalMachine -> IO Word32
fetchMem arr off um = do
let bank = umArrays um M.! fromIntegral arr
bank `V.read` fromIntegral off
allocMem :: Word32 -> UniversalMachine -> IO (Word32, UniversalMachine)
allocMem size um = do
arr <- V.replicate (fromIntegral size) 0
let idx = umArrayId um
let newArrays = M.insert (fromIntegral idx) arr (umArrays um)
return (idx, um{ umArrays = newArrays, umArrayId = idx+1 })
freeMem :: Word32 -> UniversalMachine -> IO UniversalMachine
freeMem idx um = do
let newArrays = M.delete (fromIntegral idx) (umArrays um)
return um{ umArrays = newArrays }
writeMem :: Word32 -> Word32 -> Word32 -> UniversalMachine -> IO ()
writeMem arr off num um = do
let targetArr = umArrays um M.! fromIntegral arr
targetArr `V.write` fromIntegral off $ num
incFinger :: UniversalMachine -> UniversalMachine
incFinger um@(UM { umFinger = f }) = um { umFinger = f + 1 }
opExec :: Operator -> UniversalMachine -> IO UniversalMachine
opExec oper@(Std { op = CondMove }) um = do
c <- fetchReg (argC oper) um
unless (c == 0) $ do
b <- fetchReg (argB oper) um
setReg (argA oper) b um
return um
opExec oper@(Std { op = ArrIndex }) um = do
arr <- fetchReg (argB oper) um
off <- fetchReg (argC oper) um
num <- fetchMem (fromIntegral arr) (fromIntegral off) um
setReg (argA oper) num um
return um
opExec oper@(Std { op = ArrAmend }) um = do
arr <- fetchReg (argA oper) um
off <- fetchReg (argB oper) um
num <- fetchReg (argC oper) um
writeMem (fromIntegral arr) (fromIntegral off) num um
return um
opExec oper@(Std { op = Add }) um = do
b <- fetchReg (argB oper) um
c <- fetchReg (argC oper) um
let num = b + c
setReg (argA oper) num um
return um
opExec oper@(Std { op = Mult }) um = do
b <- fetchReg (argB oper) um
c <- fetchReg (argC oper) um
let num = b * c
setReg (argA oper) num um
return um
opExec oper@(Std { op = Div }) um = do
b <- fetchReg (argB oper) um
c <- fetchReg (argC oper) um
let num = b `div` c
unless (c == 0) $ setReg (argA oper) num um
return um
opExec oper@(Std { op = NotAnd }) um = do
b <- fetchReg (argB oper) um
c <- fetchReg (argC oper) um
let num = complement (b .&. c)
setReg (argA oper) num um
return um
opExec (Std { op = Halt }) _ = error "Halted!"
opExec oper@(Std { op = Alloc }) um = do
size <- fetchReg (argC oper) um
(addr, um') <- allocMem size um
setReg (argB oper) addr um'
return um'
opExec oper@(Std { op = Abandon }) um = do
c <- fetchReg (argC oper) um
freeMem c um
opExec oper@(Std { op = Output }) um = do
c <- fetchReg (argC oper) um
BS.hPut stdout $ BS.singleton (fromIntegral c)
return um
opExec oper@(Std { op = Input }) um = do
eof <- isEOF
c <- if eof then return 0xffffffff
else liftM (fromIntegral . fromEnum) getChar
setReg (argC oper) c um
return um
opExec oper@(Std { op = LoadProg }) um = do
b <- fetchReg (argB oper) um
c <- fetchReg (argC oper) um
if b /= 0 then
do let bank = umArrays um M.! fromIntegral b
newbank <- V.clone bank
let newarrays = M.insert 0 newbank (umArrays um)
return um { umFinger = c, umArrays = newarrays }
else return (um { umFinger = c })
opExec (Spl { op = Orthography
, argA = a
, val = v }) um = do
setReg a v um
return um
bytesToWord :: BS.ByteString -> (Word32, BS.ByteString)
bytesToWord bs = let a = BS.index bs 0
b = BS.index bs 1
c = BS.index bs 2
d = BS.index bs 3
in
((fromIntegral a :: Word32) `shiftL` 24 .|.
(fromIntegral b :: Word32) `shiftL` 16 .|.
(fromIntegral c :: Word32) `shiftL` 8 .|.
(fromIntegral d :: Word32), BS.drop 4 bs)
loadProgram :: String -> IO (V.IOVector Word32)
loadProgram file = do
chars <- BS.readFile file
prog <- V.replicate (BS.length chars `div` 4) 0
go chars 0 prog
return prog
where
go bs i vec = do
let (w32, rest) = bytesToWord bs
vec `V.write` i $ w32
unless (BS.length rest < 4) $ go rest (i+1) vec
newUM :: String -> IO UniversalMachine
newUM file = do
regs <- V.replicate 8 0
progVec <- loadProgram file
let arrays = M.fromList [(0, progVec)]
putStrLn "Finished loading Universal Machine!"
return UM { umRegisters = regs
, umArrays = arrays
, umArrayId = 1
, umFinger = 0
}
spin :: UniversalMachine -> IO UniversalMachine
spin um@UM{ umFinger = finger } = do
oper <- fetchMem 0 (fromIntegral finger) um
um2 <- opExec (opDecode oper) (incFinger um)
spin um2
main :: IO ()
main = do
args <- getArgs
hSetBinaryMode stdout True
case args of
[] -> putStrLn "Usage: um <filename>"
fname : _ -> do
um <- newUM fname
spin um
return ()

5
stack.yaml Normal file
View File

@ -0,0 +1,5 @@
flags: {}
packages:
- '.'
extra-deps: []
resolver: lts-3.5

25
um.cabal Normal file
View File

@ -0,0 +1,25 @@
name: um
version: 0.1.0.0
synopsis: Initial project template from stack
-- description: Please see README.md
homepage: http://github.com/githubuser/foo#readme
-- license: BSD3
-- license-file: LICENSE
author: Example Author Name
maintainer: example@example.com
copyright: 2010 Author Here
category: Web
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
executable um
hs-source-dirs: solution
main-is: um.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O2
build-depends: base
, binary
, bytestring
, containers
, vector
default-language: Haskell2010