Skip to content

Commit 33305d8

Browse files
committed
repl script to improve interactivity
Also add formatter option. sciml seemed to have the best horizontal to vertical format tradeoff.
1 parent 30c9a4c commit 33305d8

File tree

3 files changed

+103
-44
lines changed

3 files changed

+103
-44
lines changed

2023/.JuliaFormatter.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
indent = 2
2+
margin = 80
3+
trailing_comma = false
4+
whitespace_in_kwargs = false
5+
style = "sciml"

2023/Runner.jl

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,16 @@ using Printf
1111

1212
function run_part(func, input, expected)
1313
stats = @timed func(input)
14-
Result(stats.value, expected, stats.time)
14+
Result(stats.value, expected, stats.time, stats.bytes)
1515
end
1616

17-
function run_module(mod, filenames; verbose = false)
17+
function run_module(mod, filenames; verbose=false)
1818
name = nameof(mod)
1919
ok = true
2020
for fname in filenames
2121
lines = readlines(fname == "-" ? stdin : fname)
2222
len = length(lines)
23-
expectfile = replace(fname, r"(.*)\.txt$" => s"\1.expected")
24-
expect = Dict(
25-
if expectfile != fname && isfile(expectfile)
26-
open(expectfile) do ef
27-
map(
28-
filter(
29-
!isnothing,
30-
map(l -> match(r"(part\d):\s*(.*)", l), readlines(ef)),
31-
)
32-
) do m
33-
m.captures[1] => replace(m.captures[2], r"\\n" => "\n")
34-
end
35-
end
36-
else
37-
[]
38-
end,
39-
)
23+
expect = expectedfor(fname)
4024
for func in [mod.part1, mod.part2]
4125
expected = get(expect, string(func), "")
4226
if verbose
@@ -46,15 +30,31 @@ function run_module(mod, filenames; verbose = false)
4630
println("$func: $(res.got)")
4731
if verbose
4832
time = format_seconds(res.time_sec)
33+
bytes = Base.format_bytes(res.allocated_bytes)
4934
print_message(stderr, res)
50-
println(stderr, "$func took $time on $fname")
35+
println(stderr, "$func took $time and $bytes on $fname")
5136
println(stderr, "="^40)
5237
end
5338
end
5439
end
5540
return ok
5641
end
5742

43+
expectedfile(inputfile) = replace(inputfile, r"(.*)\.txt$" => s"\1.expected")
44+
45+
function expectedfor(inputfile)
46+
expectfile = expectedfile(inputfile)
47+
if expectfile != inputfile && isfile(expectfile)
48+
open(expectfile) do ef
49+
map(m -> m.captures[1] => replace(m.captures[2], r"\\n" => "\n"),
50+
map(l -> match(r"(part\d):\s*(.*)", l), readlines(ef)) |>
51+
filter(!isnothing))
52+
end |> Dict{String, String}
53+
else
54+
Dict{String, String}()
55+
end
56+
end
57+
5858
function format_seconds(sec)
5959
if sec >= 60 * 60
6060
(m, s) = divrem(sec, 60)
@@ -66,22 +66,30 @@ function format_seconds(sec)
6666
elseif sec >= 1
6767
@sprintf("%.3fs", sec)
6868
elseif sec >= 0.001
69-
@sprintf("%.3fms", sec * 1_000)
69+
@sprintf("%.3fms", sec*1_000)
7070
else
71-
@sprintf("%.3fµs", sec * 1_000_000)
71+
@sprintf("%.3fµs", sec*1_000_000)
7272
end
7373
end
7474

7575
struct Result
7676
got::Any
7777
want::String
7878
time_sec::Float64
79+
allocated_bytes::Int
7980
end
8081

82+
const OUTCOME_SYMBOLS = Dict(:success => "",
83+
:failure => "",
84+
:unknown => "",
85+
:todo => "")
86+
const OUTCOME_BG_COLOR = Dict(:success => :light_green,
87+
:failure => :light_red,
88+
:unknown => :magenta,
89+
:todo => :cyan)
8190
function print_message(io, res::Result)
8291
o = outcome(res)
83-
sign =
84-
Dict(:success => "", :failure => "", :unknown => "", :todo => "")[o]
92+
sign = OUTCOME_SYMBOLS[o]
8593
msg = if o == :success
8694
"got $(res.got)"
8795
elseif o == :failure
@@ -93,14 +101,12 @@ function print_message(io, res::Result)
93101
elseif o == :todo
94102
"implement it, want $(res.want)"
95103
end
96-
bg = Dict(
97-
:success => :light_green,
98-
:failure => :light_red,
99-
:unknown => :magenta,
100-
:todo => :cyan,
101-
)[o]
104+
bg = OUTCOME_BG_COLOR[o]
102105
buf = IOBuffer()
103-
printstyled(IOContext(buf, :color => true), uppercase(string(o)), color = bg, reverse = true)
106+
printstyled(IOContext(buf, :color => true),
107+
uppercase(string(o)),
108+
color=bg,
109+
reverse=true)
104110
colored = String(take!(buf))
105111
println(io, "$sign $colored $msg")
106112
end
@@ -122,18 +128,16 @@ end
122128
macro run_if_main()
123129
srcfile = QuoteNode(__source__.file)
124130
mod = __module__
125-
:(
126-
if abspath(PROGRAM_FILE) == string($srcfile)
127-
args = ARGS
128-
verbose = false
129-
if isempty(ARGS)
130-
args = ["-"]
131-
elseif first(ARGS) in ["-v", "--verbose"]
132-
verbose = true
133-
args = args[2:end]
134-
end
135-
ok = Runner.run_module($mod, args, verbose = verbose)
136-
exit(ok ? 0 : 1)
131+
:(if abspath(PROGRAM_FILE) == string($srcfile)
132+
args = ARGS
133+
verbose = false
134+
if isempty(ARGS)
135+
args = ["-"]
136+
elseif first(ARGS) in ["-v", "--verbose"]
137+
verbose = true
138+
args = args[2:end]
137139
end
138-
)
140+
ok = Runner.run_module($mod, args, verbose=verbose)
141+
exit(ok ? 0 : 1)
142+
end)
139143
end

2023/repl

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/zsh
2+
# Copyright 2023 Google LLC
3+
#
4+
# Use of this source code is governed by an MIT-style
5+
# license that can be found in the LICENSE file or at
6+
# https://opensource.org/licenses/MIT.
7+
8+
# Script to start a REPL with development environment conveniences.
9+
# Usage: ./repl day1
10+
11+
set -e
12+
DAY=${1:?missing day}
13+
# ${(C)} is ucfirst
14+
MODULE=${(C)DAY}
15+
cd $DAY
16+
export JULIA_LOAD_PATH=".:..:$JULIA_LOAD_PATH"
17+
if [[ -z $SSH_TTY && -z $JULIA_EDITOR ]]; then
18+
vims=($(whence gvim mvim vim || true))
19+
export JULIA_EDITOR=${vims[1]}
20+
fi
21+
22+
read -r -d '' STARTUP <<EOT || true
23+
try
24+
@eval using Debugger
25+
catch e
26+
@warn "Need to install Debugger?" exception=(e, catch_backtrace())
27+
end
28+
try
29+
@eval using Revise
30+
catch e
31+
@warn "Need to install Revise?" exception=(e, catch_backtrace())
32+
end
33+
using $MODULE
34+
using Runner
35+
inputexample = "input.example.txt"
36+
inputactual = "input.actual.txt"
37+
inputfiles() = readdir(sort=true) |> filter(x -> occursin(r"^input\..*\.txt$", x))
38+
function inputstats()
39+
for i in inputfiles()
40+
expect = join(readlines(Runner.expectedfile(i)), " ")
41+
count = length(readlines(i))
42+
println("\$i \$count lines expected: \$expect")
43+
end
44+
end
45+
run() = Runner.run_module($MODULE, inputfiles(); verbose=true)
46+
inputstats()
47+
println("$MODULE ready, just run() or $MODULE.part1(readlines(inputexample))")
48+
EOT
49+
50+
exec julia -e "$STARTUP" -i

0 commit comments

Comments
 (0)