From 0dd497895a93bec09c911154ffefab85a9559375 Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Sat, 23 Dec 2017 12:53:06 +0000 Subject: C attempt. Probably slightly faster. No free optimisations. --- day23/part2 | 39 +++++++++--------------------------- day23/part2gen | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ day23/part2rb | 34 +++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 30 deletions(-) create mode 100755 day23/part2gen create mode 100755 day23/part2rb (limited to 'day23') diff --git a/day23/part2 b/day23/part2 index b00d666..634d447 100755 --- a/day23/part2 +++ b/day23/part2 @@ -1,34 +1,13 @@ -#!/usr/bin/env ruby +#!/bin/bash -def valof(reg_file, reg_or_int) - if reg_or_int >= 'a' && reg_or_int <= 'z' then - return reg_file[reg_or_int] || 0 - end - return reg_or_int.to_i -end +if [[ $(basename $(pwd)) != 'day23' ]] ; then + cd day23 +fi -input = $stdin.readlines.map(&:chomp) +file=$(mktemp --tmpdir=. --suffix=.c) -reg = {'a' => 1} -pc = 0 +trap "rm $file a.out" EXIT -loop do - break if pc < 0 || pc >= input.length - istr = input[pc].split - case istr[0] - when 'set' - reg[istr[1]] = valof(reg, istr[2]) - when 'sub' - reg[istr[1]] = valof(reg, istr[1]) - valof(reg, istr[2]) - when 'mul' - reg[istr[1]] = valof(reg, istr[1]) * valof(reg, istr[2]) - when 'jnz' - if valof(reg, istr[1]) != 0 then - pc += valof(reg, istr[2]) - pc -= 1 - end - end - pc += 1 -end - -puts reg['h'] +./part2gen > $file +gcc -O3 $file +./a.out diff --git a/day23/part2gen b/day23/part2gen new file mode 100755 index 0000000..2cdcdf6 --- /dev/null +++ b/day23/part2gen @@ -0,0 +1,63 @@ +#!/usr/bin/env ruby + +def gen_label(here, there) + return "label_#{here}_#{there.gsub(/-/, '_')}" +end + +input = $stdin.readlines.map(&:chomp) +lines = [] +labels = {} + +input.each_with_index do |line, i| + istr = line.split + case istr[0] + when 'set' + lines << "#{istr[1]} = #{istr[2]};" + when 'sub' + lines << "#{istr[1]} -= #{istr[2]};" + when 'mul' + lines << "#{istr[1]} *= #{istr[2]};" + when 'jnz' + lab = gen_label(i, istr[2]) + lines << "if (#{istr[1]}) goto #{lab};" + jmp = istr[2].to_i + labels[i+jmp] = [] if labels[i+jmp].nil? + labels[i+jmp] << "#{lab}:" + end +end + +labels.keys.sort.reverse.each do |i| + labels[i].each do |lab| + lines.insert(i, lab) + end +end + +puts < + +void main() { + int + a = 1, + b = 0, + c = 0, + d = 0, + e = 0, + f = 0, + g = 0, + h = 0; + +// BEGIN GENERATED CODE BLOCK + +EOT + +lines.each do |line| + puts "#{line[0] == "l" ? "" : " "} #{line}" +end + +puts <= 'a' && reg_or_int <= 'z' then + return reg_file[reg_or_int] || 0 + end + return reg_or_int.to_i +end + +input = $stdin.readlines.map(&:chomp) + +reg = {'a' => 1} +pc = 0 + +loop do + break if pc < 0 || pc >= input.length + istr = input[pc].split + case istr[0] + when 'set' + reg[istr[1]] = valof(reg, istr[2]) + when 'sub' + reg[istr[1]] = valof(reg, istr[1]) - valof(reg, istr[2]) + when 'mul' + reg[istr[1]] = valof(reg, istr[1]) * valof(reg, istr[2]) + when 'jnz' + if valof(reg, istr[1]) != 0 then + pc += valof(reg, istr[2]) + pc -= 1 + end + end + pc += 1 +end + +puts reg['h'] -- cgit v1.2.3