2022-07/08 in Nim

Signed-off-by: AKP <tom@tdpain.net>
This commit is contained in:
akp 2022-12-08 17:12:33 +00:00
parent 2cebae5f97
commit 34d3346d20
No known key found for this signature in database
GPG key ID: AA5726202C8879B7
5 changed files with 214 additions and 13 deletions

View file

@ -2,13 +2,21 @@
"day": 7,
"dir": "challenges/2022/07-noSpaceLeftOnDevice",
"implementations": {
"Nim": {
"part.1.avg": 0.005115992285999994,
"part.1.max": 0.020854849,
"part.1.min": 0.002606261,
"part.2.avg": 0.0051005765810000015,
"part.2.max": 0.018048126,
"part.2.min": 0.002556105
},
"Python": {
"part.1.avg": 0.007820404291152954,
"part.1.max": 0.027557849884033203,
"part.1.min": 0.00545811653137207,
"part.2.avg": 0.00781301736831665,
"part.2.max": 0.030576467514038086,
"part.2.min": 0.005479097366333008
"part.1.avg": 0.00848755979537964,
"part.1.max": 0.0318598747253418,
"part.1.min": 0.0057828426361083984,
"part.2.avg": 0.008544703245162964,
"part.2.max": 0.03149008750915527,
"part.2.min": 0.005964994430541992
}
},
"numRuns": 1000

View file

@ -0,0 +1,101 @@
import std/strutils
import std/tables
type
Path = ref object
parts: seq[string]
proc newPath(): Path =
new result
result.parts = newSeq[string]()
proc cd(self: Path, arg: string) =
if arg == "..":
self.parts = self.parts[0..<self.parts.len-1]
elif arg != ".":
self.parts.add(arg)
proc cwd(self: Path): string =
let x = self.parts.join("/")
if x.len == 0:
return "/"
return x
proc absInCWD(self: Path, path: string): string =
let cwd = self.cwd()
if cwd == "/":
return "/" & path
return cwd & "/" & path
type
Directories = ref object
directoryNames: seq[string]
files: TableRef[string, int]
proc newDirectories(): Directories =
new result
result.directoryNames = newSeq[string]()
result.files = newTable[string, int]()
proc addDir(self: Directories, path: string) =
if not self.directoryNames.contains(path):
self.directoryNames.add(path)
proc addFile(self: Directories, path: string, size: int) =
self.files[path] = size
proc parse(instr: string): Directories =
let dirs = newDirectories()
let fp = newPath()
var i = 0
let lines = instr.strip().splitlines()
while i < lines.len:
var line = lines[i]
if line.startsWith("$ cd"):
line.removePrefix("$ cd ")
fp.cd(line)
dirs.addDir(fp.cwd())
elif line.startsWith("$ ls"):
while i < lines.len - 1 and not lines[i + 1].startsWith("$"):
i += 1
line = lines[i]
let sp = line.split(" ")
if sp[0] == "dir":
dirs.addDir(fp.absInCWD(sp[1]))
else:
dirs.addFile(fp.absInCWD(sp[1]), parseInt(sp[0]))
i += 1
return dirs
proc calculateDirectorySize(dirs: Directories, targetDirName: string): int =
for fname, size in dirs.files.pairs():
if fname.startsWith(targetDirName & "/"):
result += size
proc partOne*(instr: string): int =
let dirs = parse(instr)
for dirName in dirs.directoryNames:
let size = calculateDirectorySize(dirs, dirName)
if size <= 100000:
result += size
proc partTwo*(instr: string): int =
let
dirs = parse(instr)
used = 70000000 - calculateDirectorySize(dirs, "")
amountToDelete = 30000000 - used
var opts: seq[int]
for dirName in dirs.directoryNames:
let size = calculateDirectorySize(dirs, dirName)
if size >= amountToDelete:
opts.add(size)
return min(opts)

View file

@ -2,14 +2,22 @@
"day": 8,
"dir": "challenges/2022/08-treetopTreeHouse",
"implementations": {
"Nim": {
"part.1.avg": 0.006382409829000001,
"part.1.max": 0.026628604,
"part.1.min": 0.004007148,
"part.2.avg": 0.007344551142000002,
"part.2.max": 0.034047325,
"part.2.min": 0.004595712
},
"Python": {
"part.1.avg": 0.033502077102661135,
"part.1.max": 0.06080937385559082,
"part.1.min": 0.023911237716674805,
"part.2.avg": 0.04170952320098877,
"part.2.max": 0.0762169361114502,
"part.2.min": 0.02996683120727539
"part.1.avg": 0.0385476336479187,
"part.1.max": 0.09098124504089355,
"part.1.min": 0.025599002838134766,
"part.2.avg": 0.04808542013168335,
"part.2.max": 0.1426246166229248,
"part.2.min": 0.031610965728759766
}
},
"numRuns": 500
"numRuns": 1000
}

View file

@ -0,0 +1,84 @@
import std/tables
import std/strutils
import std/sequtils
type
Coordinate = (int, int)
Forest = ref Table[Coordinate, int]
proc parse(instr: string): (Forest, Coordinate) =
var forest = newTable[Coordinate, int]()
let lines = instr.strip().splitlines()
var
x = 0
y = 0
while x < lines.len:
y = 0
while y < lines[x].len:
forest[(x, y)] = parseInt($lines[x][y])
y += 1
x += 1
return (forest, (x, y))
proc areAdjacentsLower(forest: Forest, initialPos: Coordinate, nextPos: proc(pos: Coordinate): Coordinate): bool =
let height = forest[initialPos]
var pos = nextPos(initialPos)
while forest.contains(pos):
if forest[pos] >= height:
return false
pos = nextPos(pos)
return true
proc getViewingDistance(forest: Forest, initialPos: Coordinate, nextPos: proc(pos: Coordinate): Coordinate): int =
let height = forest[initialPos]
var pos = nextPos(initialPos)
while forest.contains(pos):
result += 1
if forest[pos] >= height:
break
pos = nextPos(pos)
proc partOne*(instr: string): int =
let
(forest, maxPos) = parse(instr)
(maxX, maxY) = maxPos
for treePos in forest.keys():
let (x, y) = treePos
if x == 0 or y == 0 or x == maxX or y == maxY:
result += 1
continue
if areAdjacentsLower(forest, treePos, proc(c: Coordinate): Coordinate = (c[0] - 1, c[1])):
result += 1
continue
if areAdjacentsLower(forest, treePos, proc(c: Coordinate): Coordinate = (c[0] + 1, c[1])):
result += 1
continue
if areAdjacentsLower(forest, treePos, proc(c: Coordinate): Coordinate = (c[0], c[1] - 1)):
result += 1
continue
if areAdjacentsLower(forest, treePos, proc(c: Coordinate): Coordinate = (c[0], c[1] + 1)):
result += 1
proc partTwo*(instr: string): int =
let (forest, _) = parse(instr)
for treePos in forest.keys():
let
view_left = getViewingDistance(forest, treePos, proc(c: Coordinate): Coordinate = (c[0] - 1, c[1]))
view_right = getViewingDistance(forest, treePos, proc(c: Coordinate): Coordinate = (c[0] + 1, c[1]))
view_up = getViewingDistance(forest, treePos, proc(c: Coordinate): Coordinate = (c[0], c[1] - 1))
view_down = getViewingDistance(forest, treePos, proc(c: Coordinate): Coordinate = (c[0], c[1] + 1))
let senic = view_left * view_right * view_up * view_down
if senic > result:
result = senic

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Before After
Before After