Skip to content

Instantly share code, notes, and snippets.

@rhardih

rhardih/7.in Secret

Last active December 5, 2020 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rhardih/f2a05ee0c34883ad805e50386497d483 to your computer and use it in GitHub Desktop.
Save rhardih/f2a05ee0c34883ad805e50386497d483 to your computer and use it in GitHub Desktop.
Files used in blog series: Spelunking Advent of Code, Some Assembly Required
lf AND lq -> ls
iu RSHIFT 1 -> jn
bo OR bu -> bv
gj RSHIFT 1 -> hc
et RSHIFT 2 -> eu
bv AND bx -> by
is OR it -> iu
b OR n -> o
gf OR ge -> gg
NOT kt -> ku
ea AND eb -> ed
kl OR kr -> ks
hi AND hk -> hl
au AND av -> ax
lf RSHIFT 2 -> lg
dd RSHIFT 3 -> df
eu AND fa -> fc
df AND dg -> di
ip LSHIFT 15 -> it
NOT el -> em
et OR fe -> ff
fj LSHIFT 15 -> fn
t OR s -> u
ly OR lz -> ma
ko AND kq -> kr
NOT fx -> fy
et RSHIFT 1 -> fm
eu OR fa -> fb
dd RSHIFT 2 -> de
NOT go -> gp
kb AND kd -> ke
hg OR hh -> hi
jm LSHIFT 1 -> kg
NOT cn -> co
jp RSHIFT 2 -> jq
jp RSHIFT 5 -> js
1 AND io -> ip
eo LSHIFT 15 -> es
1 AND jj -> jk
g AND i -> j
ci RSHIFT 3 -> ck
gn AND gp -> gq
fs AND fu -> fv
lj AND ll -> lm
jk LSHIFT 15 -> jo
iu RSHIFT 3 -> iw
NOT ii -> ij
1 AND cc -> cd
bn RSHIFT 3 -> bp
NOT gw -> gx
NOT ft -> fu
jn OR jo -> jp
iv OR jb -> jc
hv OR hu -> hw
19138 -> b
gj RSHIFT 5 -> gm
hq AND hs -> ht
dy RSHIFT 1 -> er
ao OR an -> ap
ld OR le -> lf
bk LSHIFT 1 -> ce
bz AND cb -> cc
bi LSHIFT 15 -> bm
il AND in -> io
af AND ah -> ai
as RSHIFT 1 -> bl
lf RSHIFT 3 -> lh
er OR es -> et
NOT ax -> ay
ci RSHIFT 1 -> db
et AND fe -> fg
lg OR lm -> ln
k AND m -> n
hz RSHIFT 2 -> ia
kh LSHIFT 1 -> lb
NOT ey -> ez
NOT di -> dj
dz OR ef -> eg
lx -> a
NOT iz -> ja
gz LSHIFT 15 -> hd
ce OR cd -> cf
fq AND fr -> ft
at AND az -> bb
ha OR gz -> hb
fp AND fv -> fx
NOT gb -> gc
ia AND ig -> ii
gl OR gm -> gn
0 -> c
NOT ca -> cb
bn RSHIFT 1 -> cg
c LSHIFT 1 -> t
iw OR ix -> iy
kg OR kf -> kh
dy OR ej -> ek
km AND kn -> kp
NOT fc -> fd
hz RSHIFT 3 -> ib
NOT dq -> dr
NOT fg -> fh
dy RSHIFT 2 -> dz
kk RSHIFT 2 -> kl
1 AND fi -> fj
NOT hr -> hs
jp RSHIFT 1 -> ki
bl OR bm -> bn
1 AND gy -> gz
gr AND gt -> gu
db OR dc -> dd
de OR dk -> dl
as RSHIFT 5 -> av
lf RSHIFT 5 -> li
hm AND ho -> hp
cg OR ch -> ci
gj AND gu -> gw
ge LSHIFT 15 -> gi
e OR f -> g
fp OR fv -> fw
fb AND fd -> fe
cd LSHIFT 15 -> ch
b RSHIFT 1 -> v
at OR az -> ba
bn RSHIFT 2 -> bo
lh AND li -> lk
dl AND dn -> do
eg AND ei -> ej
ex AND ez -> fa
NOT kp -> kq
NOT lk -> ll
x AND ai -> ak
jp OR ka -> kb
NOT jd -> je
iy AND ja -> jb
jp RSHIFT 3 -> jr
fo OR fz -> ga
df OR dg -> dh
gj RSHIFT 2 -> gk
gj OR gu -> gv
NOT jh -> ji
ap LSHIFT 1 -> bj
NOT ls -> lt
ir LSHIFT 1 -> jl
bn AND by -> ca
lv LSHIFT 15 -> lz
ba AND bc -> bd
cy LSHIFT 15 -> dc
ln AND lp -> lq
x RSHIFT 1 -> aq
gk OR gq -> gr
NOT kx -> ky
jg AND ji -> jj
bn OR by -> bz
fl LSHIFT 1 -> gf
bp OR bq -> br
he OR hp -> hq
et RSHIFT 5 -> ew
iu RSHIFT 2 -> iv
gl AND gm -> go
x OR ai -> aj
hc OR hd -> he
lg AND lm -> lo
lh OR li -> lj
da LSHIFT 1 -> du
fo RSHIFT 2 -> fp
gk AND gq -> gs
bj OR bi -> bk
lf OR lq -> lr
cj AND cp -> cr
hu LSHIFT 15 -> hy
1 AND bh -> bi
fo RSHIFT 3 -> fq
NOT lo -> lp
hw LSHIFT 1 -> iq
dd RSHIFT 1 -> dw
dt LSHIFT 15 -> dx
dy AND ej -> el
an LSHIFT 15 -> ar
aq OR ar -> as
1 AND r -> s
fw AND fy -> fz
NOT im -> in
et RSHIFT 3 -> ev
1 AND ds -> dt
ec AND ee -> ef
NOT ak -> al
jl OR jk -> jm
1 AND en -> eo
lb OR la -> lc
iu AND jf -> jh
iu RSHIFT 5 -> ix
bo AND bu -> bw
cz OR cy -> da
iv AND jb -> jd
iw AND ix -> iz
lf RSHIFT 1 -> ly
iu OR jf -> jg
NOT dm -> dn
lw OR lv -> lx
gg LSHIFT 1 -> ha
lr AND lt -> lu
fm OR fn -> fo
he RSHIFT 3 -> hg
aj AND al -> am
1 AND kz -> la
dy RSHIFT 5 -> eb
jc AND je -> jf
cm AND co -> cp
gv AND gx -> gy
ev OR ew -> ex
jp AND ka -> kc
fk OR fj -> fl
dy RSHIFT 3 -> ea
NOT bs -> bt
NOT ag -> ah
dz AND ef -> eh
cf LSHIFT 1 -> cz
NOT cv -> cw
1 AND cx -> cy
de AND dk -> dm
ck AND cl -> cn
x RSHIFT 5 -> aa
dv LSHIFT 1 -> ep
he RSHIFT 2 -> hf
NOT bw -> bx
ck OR cl -> cm
bp AND bq -> bs
as OR bd -> be
he AND hp -> hr
ev AND ew -> ey
1 AND lu -> lv
kk RSHIFT 3 -> km
b AND n -> p
NOT kc -> kd
lc LSHIFT 1 -> lw
km OR kn -> ko
id AND if -> ig
ih AND ij -> ik
jr AND js -> ju
ci RSHIFT 5 -> cl
hz RSHIFT 1 -> is
1 AND ke -> kf
NOT gs -> gt
aw AND ay -> az
x RSHIFT 2 -> y
ab AND ad -> ae
ff AND fh -> fi
ci AND ct -> cv
eq LSHIFT 1 -> fk
gj RSHIFT 3 -> gl
u LSHIFT 1 -> ao
NOT bb -> bc
NOT hj -> hk
kw AND ky -> kz
as AND bd -> bf
dw OR dx -> dy
br AND bt -> bu
kk AND kv -> kx
ep OR eo -> eq
he RSHIFT 1 -> hx
ki OR kj -> kk
NOT ju -> jv
ek AND em -> en
kk RSHIFT 5 -> kn
NOT eh -> ei
hx OR hy -> hz
ea OR eb -> ec
s LSHIFT 15 -> w
fo RSHIFT 1 -> gh
kk OR kv -> kw
bn RSHIFT 5 -> bq
NOT ed -> ee
1 AND ht -> hu
cu AND cw -> cx
b RSHIFT 5 -> f
kl AND kr -> kt
iq OR ip -> ir
ci RSHIFT 2 -> cj
cj OR cp -> cq
o AND q -> r
dd RSHIFT 5 -> dg
b RSHIFT 2 -> d
ks AND ku -> kv
b RSHIFT 3 -> e
d OR j -> k
NOT p -> q
NOT cr -> cs
du OR dt -> dv
kf LSHIFT 15 -> kj
NOT ac -> ad
fo RSHIFT 5 -> fr
hz OR ik -> il
jx AND jz -> ka
gh OR gi -> gj
kk RSHIFT 1 -> ld
hz RSHIFT 5 -> ic
as RSHIFT 2 -> at
NOT jy -> jz
1 AND am -> an
ci OR ct -> cu
hg AND hh -> hj
jq OR jw -> jx
v OR w -> x
la LSHIFT 15 -> le
dh AND dj -> dk
dp AND dr -> ds
jq AND jw -> jy
au OR av -> aw
NOT bf -> bg
z OR aa -> ab
ga AND gc -> gd
hz AND ik -> im
jt AND jv -> jw
z AND aa -> ac
jr OR js -> jt
hb LSHIFT 1 -> hv
hf OR hl -> hm
ib OR ic -> id
fq OR fr -> fs
cq AND cs -> ct
ia OR ig -> ih
dd OR do -> dp
d AND j -> l
ib AND ic -> ie
as RSHIFT 3 -> au
be AND bg -> bh
dd AND do -> dq
NOT l -> m
1 AND gd -> ge
y AND ae -> ag
fo AND fz -> gb
NOT ie -> if
e AND f -> h
x RSHIFT 3 -> z
y OR ae -> af
hf AND hl -> hn
NOT h -> i
NOT hn -> ho
he RSHIFT 5 -> hh
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
interface SignalProvider {
public int getSignal();
}
class SignalInput extends Observable implements SignalProvider {
private int signal;
public int getSignal() {
return this.signal;
}
public void setSignal(int signal) {
this.signal = signal;
setChanged();
notifyObservers();
}
}
class Wire extends Observable implements SignalProvider, Observer {
private String identifier;
private int signal;
public Wire(String identifier) {
this.identifier = identifier;
this.signal = -1;
}
public String getIdentifier() {
return identifier;
}
public int getSignal() {
return signal;
}
public void setSignal(int signal) {
this.signal = signal;
setChanged();
notifyObservers();
}
@Override
public void update(Observable observable, Object arg) {
SignalProvider signalProvider = (SignalProvider) observable;
setSignal(signalProvider.getSignal());
}
}
abstract class Gate extends Observable implements SignalProvider, Observer {
private int signal;
public int getSignal() {
return signal;
}
public void setSignal(int signal) {
this.signal = signal;
setChanged();
notifyObservers();
}
@Override
public abstract void update(Observable observable, Object arg);
}
class AndGate extends Gate {
private int firstInputSignal;
public AndGate() {
this.firstInputSignal = -1;
}
@Override
public void update(Observable observable, Object arg) {
SignalProvider signalProvider = (SignalProvider) observable;
int inputSignal = signalProvider.getSignal();
if (this.firstInputSignal == -1) {
this.firstInputSignal = inputSignal;
} else {
setSignal((this.firstInputSignal & inputSignal));
}
}
}
class OrGate extends Gate {
private int firstInputSignal;
public OrGate() {
this.firstInputSignal = -1;
}
@Override
public void update(Observable observable, Object arg) {
SignalProvider signalProvider = (SignalProvider) observable;
int inputSignal = signalProvider.getSignal();
if (this.firstInputSignal == -1) {
this.firstInputSignal = inputSignal;
} else {
setSignal((this.firstInputSignal | inputSignal));
}
}
}
class LeftShiftGate extends Gate {
private int positions;
public LeftShiftGate(int positions) {
this.positions = positions;
}
@Override
public void update(Observable observable, Object arg) {
SignalProvider signalProvider = (SignalProvider) observable;
int inputSignal = signalProvider.getSignal();
setSignal((inputSignal << this.positions));
}
}
class RightShiftGate extends Gate {
private int positions;
public RightShiftGate(int positions) {
this.positions = positions;
}
@Override
public void update(Observable observable, Object arg) {
SignalProvider signalProvider = (SignalProvider) observable;
int inputSignal = signalProvider.getSignal();
setSignal((inputSignal >> this.positions));
}
}
class NotGate extends Gate {
@Override
public void update(Observable observable, Object arg) {
SignalProvider signalProvider = (SignalProvider) observable;
int inputSignal = signalProvider.getSignal();
setSignal(~inputSignal);
}
}
interface Instruction {
void performOn(Circuit circuit);
}
class SignalImmediateInstruction implements Instruction {
private String outputWireIdentifier;
private int signal;
private SignalInput signalInput;
public SignalImmediateInstruction(String outputWireIdentifier, int signal) {
this.outputWireIdentifier = outputWireIdentifier;
this.signal = signal;
this.signalInput = new SignalInput();
}
public void performOn(Circuit circuit) {
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
this.signalInput.addObserver(outputWire);
}
public void trigger() {
this.signalInput.setSignal(this.signal);
}
}
class SignalWireInstruction implements Instruction {
private String inputWireIdentifier;
private String outputWireIdentifier;
public SignalWireInstruction(String inputWireIdentifier, String outputWireIdentifier) {
this.inputWireIdentifier = inputWireIdentifier;
this.outputWireIdentifier = outputWireIdentifier;
}
public void performOn(Circuit circuit) {
Wire inputWire = circuit.getWire(this.inputWireIdentifier);
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
inputWire.addObserver(outputWire);
}
}
class AndInstruction implements Instruction {
private String inputWireIdentifier0;
private String inputWireIdentifier1;
private String outputWireIdentifier;
public AndInstruction(
String inputWireIdentifier0, String inputWireIdentifier1, String outputWireIdentifier) {
this.inputWireIdentifier0 = inputWireIdentifier0;
this.inputWireIdentifier1 = inputWireIdentifier1;
this.outputWireIdentifier = outputWireIdentifier;
}
public void performOn(Circuit circuit) {
Wire inputWire0 = circuit.getWire(this.inputWireIdentifier0);
Wire inputWire1 = circuit.getWire(this.inputWireIdentifier1);
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
AndGate andGate = new AndGate();
inputWire0.addObserver(andGate);
inputWire1.addObserver(andGate);
andGate.addObserver(outputWire);
}
}
class AndImmediateInstruction implements Instruction {
private String inputWireIdentifier;
private String outputWireIdentifier;
private int signal;
public AndImmediateInstruction(
String inputWireIdentifier, String outputWireIdentifier, int signal) {
this.inputWireIdentifier = inputWireIdentifier;
this.outputWireIdentifier = outputWireIdentifier;
this.signal = signal;
}
public void performOn(Circuit circuit) {
Wire inputWire = circuit.getWire(this.inputWireIdentifier);
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
SignalInput signalInput = new SignalInput();
AndGate andGate = new AndGate();
signalInput.addObserver(andGate);
inputWire.addObserver(andGate);
andGate.addObserver(outputWire);
signalInput.setSignal(this.signal);
}
}
class OrInstruction implements Instruction {
private String inputWireIdentifier0;
private String inputWireIdentifier1;
private String outputWireIdentifier;
public OrInstruction(
String inputWireIdentifier0, String inputWireIdentifier1, String outputWireIdentifier) {
this.inputWireIdentifier0 = inputWireIdentifier0;
this.inputWireIdentifier1 = inputWireIdentifier1;
this.outputWireIdentifier = outputWireIdentifier;
}
public void performOn(Circuit circuit) {
Wire inputWire0 = circuit.getWire(this.inputWireIdentifier0);
Wire inputWire1 = circuit.getWire(this.inputWireIdentifier1);
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
OrGate orGate = new OrGate();
inputWire0.addObserver(orGate);
inputWire1.addObserver(orGate);
orGate.addObserver(outputWire);
}
}
class leftShiftInstruction implements Instruction {
private String inputWireIdentifier;
private String outputWireIdentifier;
private int positions;
public leftShiftInstruction(
String inputWireIdentifier, String outputWireIdentifier, int positions) {
this.inputWireIdentifier = inputWireIdentifier;
this.outputWireIdentifier = outputWireIdentifier;
this.positions = positions;
}
public void performOn(Circuit circuit) {
Wire inputWire = circuit.getWire(this.inputWireIdentifier);
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
LeftShiftGate leftShiftGate = new LeftShiftGate(this.positions);
inputWire.addObserver(leftShiftGate);
leftShiftGate.addObserver(outputWire);
}
}
class rightShiftInstruction implements Instruction {
private String inputWireIdentifier;
private String outputWireIdentifier;
private int positions;
public rightShiftInstruction(
String inputWireIdentifier, String outputWireIdentifier, int positions) {
this.inputWireIdentifier = inputWireIdentifier;
this.outputWireIdentifier = outputWireIdentifier;
this.positions = positions;
}
public void performOn(Circuit circuit) {
Wire inputWire = circuit.getWire(this.inputWireIdentifier);
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
RightShiftGate rightShiftGate = new RightShiftGate(this.positions);
inputWire.addObserver(rightShiftGate);
rightShiftGate.addObserver(outputWire);
}
}
class NotInstruction implements Instruction {
private String inputWireIdentifier;
private String outputWireIdentifier;
public NotInstruction(String inputWireIdentifier, String outputWireIdentifier) {
this.inputWireIdentifier = inputWireIdentifier;
this.outputWireIdentifier = outputWireIdentifier;
}
public void performOn(Circuit circuit) {
Wire inputWire = circuit.getWire(this.inputWireIdentifier);
Wire outputWire = circuit.getWire(this.outputWireIdentifier);
NotGate notGate = new NotGate();
inputWire.addObserver(notGate);
notGate.addObserver(outputWire);
}
}
class InstructionFactory {
public static Instruction getInstruction(String instruction) {
// Patterns
Pattern andImmediatePattern = Pattern.compile("^(\\d+) AND ([a-z]+) -> ([a-z]+)$");
Pattern andPattern = Pattern.compile("^([a-z]+) AND ([a-z]+) -> ([a-z]+)$");
Pattern leftShiftPattern = Pattern.compile("^([a-z]+) LSHIFT (\\d+) -> ([a-z]+)$");
Pattern notPattern = Pattern.compile("^NOT ([a-z]+) -> ([a-z]+)$");
Pattern orPattern = Pattern.compile("^([a-z]+) OR ([a-z]+) -> ([a-z]+)$");
Pattern rightShiftPattern = Pattern.compile("^([a-z]+) RSHIFT (\\d+) -> ([a-z]+)$");
Pattern signalImmediatePattern = Pattern.compile("^(\\d+) -> ([a-z]+)$");
Pattern signalWirePattern = Pattern.compile("^([a-z]+) -> ([a-z]+)$");
// Matchers
Matcher andImmediateMatcher = andImmediatePattern.matcher(instruction);
Matcher andMatcher = andPattern.matcher(instruction);
Matcher leftShiftMatcher = leftShiftPattern.matcher(instruction);
Matcher notMatcher = notPattern.matcher(instruction);
Matcher orMatcher = orPattern.matcher(instruction);
Matcher rightShiftMatcher = rightShiftPattern.matcher(instruction);
Matcher signalImmediateMatcher = signalImmediatePattern.matcher(instruction);
Matcher signalWireMatcher = signalWirePattern.matcher(instruction);
if (signalImmediateMatcher.find()) {
return new SignalImmediateInstruction(
signalImmediateMatcher.group(2), Short.parseShort(signalImmediateMatcher.group(1)));
} else if (signalWireMatcher.find()) {
return new SignalWireInstruction(signalWireMatcher.group(1), signalWireMatcher.group(2));
} else if (andMatcher.find()) {
return new AndInstruction(andMatcher.group(1), andMatcher.group(2), andMatcher.group(3));
} else if (andImmediateMatcher.find()) {
return new AndImmediateInstruction(
andImmediateMatcher.group(2),
andImmediateMatcher.group(3),
Short.parseShort(andImmediateMatcher.group(1)));
} else if (orMatcher.find()) {
return new OrInstruction(orMatcher.group(1), orMatcher.group(2), orMatcher.group(3));
} else if (leftShiftMatcher.find()) {
return new leftShiftInstruction(
leftShiftMatcher.group(1),
leftShiftMatcher.group(3),
Short.parseShort(leftShiftMatcher.group(2)));
} else if (rightShiftMatcher.find()) {
return new rightShiftInstruction(
rightShiftMatcher.group(1),
rightShiftMatcher.group(3),
Short.parseShort(rightShiftMatcher.group(2)));
} else if (notMatcher.find()) {
return new NotInstruction(notMatcher.group(1), notMatcher.group(2));
}
return null;
}
}
class Circuit {
private HashMap<String, Wire> wires;
public Circuit() {
this.wires = new HashMap<String, Wire>();
}
// Get existing or create and return a new wire for the circuit.
public Wire getWire(String identifier) {
Wire wire;
if (this.wires.containsKey(identifier)) {
wire = this.wires.get(identifier);
} else {
wire = new Wire(identifier);
wires.put(identifier, wire);
}
return wire;
}
public String getWireSignal(String wireIdentifier) {
return String.valueOf(wires.get(wireIdentifier).getSignal());
}
}
class SomeAssemblyRequired {
public static void main(String[] args) {
Circuit circuit = new Circuit();
Scanner scanner = new Scanner(System.in);
List<SignalImmediateInstruction> signalImmediateInstructions =
new ArrayList<SignalImmediateInstruction>();
while (scanner.hasNext()) {
Instruction instruction = InstructionFactory.getInstruction(scanner.nextLine());
instruction.performOn(circuit);
if (instruction instanceof SignalImmediateInstruction) {
signalImmediateInstructions.add((SignalImmediateInstruction) instruction);
}
}
scanner.close();
// To run the circuit we trigger all direct value assignments, which should
// in turn trigger its dependents, and so on and so forth.
for (SignalImmediateInstruction instruction : signalImmediateInstructions) {
instruction.trigger();
}
System.out.println("Signal ultimately provided to wire a: " + circuit.getWireSignal("a"));
}
}
MAX_INT = 2**16
circuit = {}
queue = Queue.new
STDIN.read.split("\n").each { |i| queue.push i }
def bound(n)
if n > MAX_INT
n - MAX_INT
elsif n < 0
n + MAX_INT
else
n
end
end
until queue.empty?
instruction = queue.pop
case instruction
when /^(\d+) -> ([a-z]+)$/
circuit[$2] = $1.to_i
next
when /^([a-z]+) -> ([a-z]+)$/
if circuit.key?($1)
circuit[$2] = circuit[$1]
next
end
when /^([a-z]+) AND ([a-z]+) -> ([a-z]+)$/
if circuit.key?($1) && circuit.key?($2)
circuit[$3] = bound(circuit[$1] & circuit[$2])
next
end
when /^(\d+) AND ([a-z]+) -> ([a-z]+)$/
if circuit.key?($2)
circuit[$3] = $1.to_i & circuit[$2]
next
end
when /^([a-z]+) OR ([a-z]+) -> ([a-z]+)$/
if circuit.key?($1) && circuit.key?($2)
circuit[$3] = bound(circuit[$1] | circuit[$2])
next
end
when /^([a-z]+) LSHIFT (\d+) -> ([a-z]+)$/
if circuit.key?($1)
circuit[$3] = bound(circuit[$1] << $2.to_i)
next
end
when /^([a-z]+) RSHIFT (\d+) -> ([a-z]+)$/
if circuit.key?($1)
circuit[$3] = bound(circuit[$1] >> $2.to_i)
next
end
when /^NOT ([a-z]+) -> ([a-z]+)$/
if circuit.key?($1)
circuit[$2] = bound(~circuit[$1])
next
end
end
queue.push(instruction)
end
puts "Signal ultimately provided to wire a: #{circuit["a"]}"
MAX_INT = 2**16
circuit = {}
instructions = STDIN.read.split("\n")
resolved = []
def bound(n)
if n > MAX_INT
n - MAX_INT
elsif n < 0
n + MAX_INT
else
n
end
end
# Seed the sorted instructions with the initial direct value assignments
sorted, instructions = instructions.partition do |ins|
val = /^(\d+) -> ([a-z]+)$/.match(ins)
resolved << $~[2] unless $~.nil?
val
end
until instructions.empty?
tmp = []
plucked, instructions = instructions.partition do |ins|
exp, out = ins.split(" -> ")
val = false
case exp
when /^([a-z]+)$/
val = resolved.include?($1)
when /^([a-z]+) AND ([a-z]+)$/
val = resolved.include?($1) && resolved.include?($2)
when /^(\d+) AND ([a-z]+)$/
val = resolved.include?($2)
when /^([a-z]+) OR ([a-z]+)$/
val = resolved.include?($1) && resolved.include?($2)
when /^([a-z]+) LSHIFT (\d+)$/
val = resolved.include?($1)
when /^([a-z]+) RSHIFT (\d+)$/
val = resolved.include?($1)
when /^NOT ([a-z]+)$/
val = resolved.include?($1)
end
tmp << out if val
val
end
resolved += tmp
sorted += plucked
end
sorted.each do |instruction|
case instruction
when /^(\d+) -> ([a-z]+)$/
circuit[$2] = $1.to_i
when /^([a-z]+) -> ([a-z]+)$/
circuit[$2] = circuit[$1]
when /^([a-z]+) AND ([a-z]+) -> ([a-z]+)$/
circuit[$3] = bound(circuit[$1] & circuit[$2])
when /^(\d+) AND ([a-z]+) -> ([a-z]+)$/
circuit[$3] = $1.to_i & circuit[$2]
when /^([a-z]+) OR ([a-z]+) -> ([a-z]+)$/
circuit[$3] = bound(circuit[$1] | circuit[$2])
when /^([a-z]+) LSHIFT (\d+) -> ([a-z]+)$/
circuit[$3] = bound(circuit[$1] << $2.to_i)
when /^([a-z]+) RSHIFT (\d+) -> ([a-z]+)$/
circuit[$3] = bound(circuit[$1] >> $2.to_i)
when /^NOT ([a-z]+) -> ([a-z]+)$/
circuit[$2] = bound(~circuit[$1])
end
end
puts "Signal ultimately provided to wire a: #{circuit["a"]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment