From 3fca76a62cacdbded77b78308fb4bd9511b8bf17 Mon Sep 17 00:00:00 2001 From: FrederikBaerentsen Date: Sat, 14 Dec 2024 10:46:57 +0100 Subject: [PATCH] Solved 2024/14 --- 2022/08/8.md | 125 ++++++++++++++++++++++ 2022/08/solution.py | 155 +++++++++++++++++++++++++++ 2022/day8/day8_part1.py | 2 +- 2024/14/14.md | 177 +++++++++++++++++++++++++++++++ 2024/14/solution.py | 135 +++++++++++++++++++++++ __pycache__/fred.cpython-311.pyc | Bin 25690 -> 26403 bytes fred.py | 20 +++- 7 files changed, 608 insertions(+), 6 deletions(-) create mode 100644 2022/08/8.md create mode 100644 2022/08/solution.py create mode 100644 2024/14/14.md create mode 100644 2024/14/solution.py diff --git a/2022/08/8.md b/2022/08/8.md new file mode 100644 index 0000000..2acb1d2 --- /dev/null +++ b/2022/08/8.md @@ -0,0 +1,125 @@ +## \-\-- Day 8: Treetop Tree House \-\-- + +The expedition comes across a peculiar patch of tall trees all planted +carefully in a grid. The Elves explain that a previous expedition +planted these trees as a reforestation effort. Now, they\'re curious if +this would be a good location for a [tree +house](https://en.wikipedia.org/wiki/Tree_house). + +First, determine whether there is enough tree cover here to keep a tree +house *hidden*. To do this, you need to count the number of trees that +are *visible from outside the grid* when looking directly along a row or +column. + +The Elves have already launched a +[quadcopter](https://en.wikipedia.org/wiki/Quadcopter) +to generate a map with the height of each tree ([your puzzle +input]{title="The Elves have already launched a quadcopter (your puzzle input)."}). +For example: + + 30373 + 25512 + 65332 + 33549 + 35390 + +Each tree is represented as a single digit whose value is its height, +where `0` is the shortest and `9` is the tallest. + +A tree is *visible* if all of the other trees between it and an edge of +the grid are *shorter* than it. Only consider trees in the same row or +column; that is, only look up, down, left, or right from any given tree. + +All of the trees around the edge of the grid are *visible* - since they +are already on the edge, there are no trees to block the view. In this +example, that only leaves the *interior nine trees* to consider: + +- The top-left `5` is *visible* from the left and top. (It isn\'t + visible from the right or bottom since other trees of height `5` are + in the way.) +- The top-middle `5` is *visible* from the top and right. +- The top-right `1` is not visible from any direction; for it to be + visible, there would need to only be trees of height *0* between it + and an edge. +- The left-middle `5` is *visible*, but only from the right. +- The center `3` is not visible from any direction; for it to be + visible, there would need to be only trees of at most height `2` + between it and an edge. +- The right-middle `3` is *visible* from the right. +- In the bottom row, the middle `5` is *visible*, but the `3` and `4` + are not. + +With 16 trees visible on the edge and another 5 visible in the interior, +a total of `21` trees are visible in this arrangement. + +Consider your map; *how many trees are visible from outside the grid?* + +Your puzzle answer was `1690`. + +The first half of this puzzle is complete! It provides one gold star: \* + +## \-\-- Part Two \-\-- {#part2} + +Content with the amount of tree cover available, the Elves just need to +know the best spot to build their tree house: they would like to be able +to see a lot of *trees*. + +To measure the viewing distance from a given tree, look up, down, left, +and right from that tree; stop if you reach an edge or at the first tree +that is the same height or taller than the tree under consideration. (If +a tree is right on the edge, at least one of its viewing distances will +be zero.) + +The Elves don\'t care about distant trees taller than those found by the +rules above; the proposed tree house has large +[eaves](https://en.wikipedia.org/wiki/Eaves) to keep it +dry, so they wouldn\'t be able to see higher than the tree house anyway. + +In the example above, consider the middle `5` in the second row: + + 30373 + 25512 + 65332 + 33549 + 35390 + +- Looking up, its view is not blocked; it can see `1` tree (of height + `3`). +- Looking left, its view is blocked immediately; it can see only `1` + tree (of height `5`, right next to it). +- Looking right, its view is not blocked; it can see `2` trees. +- Looking down, its view is blocked eventually; it can see `2` trees + (one of height `3`, then the tree of height `5` that blocks its + view). + +A tree\'s *scenic score* is found by *multiplying together* its viewing +distance in each of the four directions. For this tree, this is `4` +(found by multiplying `1 * 1 * 2 * 2`). + +However, you can do even better: consider the tree of height `5` in the +middle of the fourth row: + + 30373 + 25512 + 65332 + 33549 + 35390 + +- Looking up, its view is blocked at `2` trees (by another tree with a + height of `5`). +- Looking left, its view is not blocked; it can see `2` trees. +- Looking down, its view is also not blocked; it can see `1` tree. +- Looking right, its view is blocked at `2` trees (by a massive tree + of height `9`). + +This tree\'s scenic score is `8` (`2 * 2 * 1 * 2`); this is the ideal +spot for the tree house. + +Consider each tree on your map. *What is the highest scenic score +possible for any tree?* + +Answer: + +Although it hasn\'t changed, you can still [get your puzzle +input](8/input). + diff --git a/2022/08/solution.py b/2022/08/solution.py new file mode 100644 index 0000000..3668f82 --- /dev/null +++ b/2022/08/solution.py @@ -0,0 +1,155 @@ +#!/bin/python3 +import sys,time,re +from pprint import pprint +sys.path.insert(0, '../../') +from fred import list2int,get_re,nprint,lprint,loadFile,nprint,get_value_in_direction,grid_valid,toGrid,addTuples +start_time = time.time() + +input_f = 'test' + +######################################### +# # +# Part 1 # +# # +######################################### +def part1(): + grid = toGrid(input_f) + nprint(grid) + + directions = { + 'up': (-1, 0), + 'down': (1, 0), + 'left': (0, -1), + 'right': (0, 1), + } + + visible = [] + for r,row in enumerate(grid): + for c,col in enumerate(row): + if r == 0 or r == len(grid)-1 or c == 0 or c == len(row)-1: + visible.append((r,c)) + else: + #print(r,c) + cur = get_value_in_direction(grid,(r,c)) + + x = [] + test = {} + length = 0 + notVisible = False + (nr,nc) = (r,c) + #print((r,c),cur) + for d in directions.keys(): + #print(d) + if d == 'up': + length = r + if d == 'down': + length = len(grid)-r-1 + if d == 'left': + length = c + if d == 'right': + length = len(row)-c-1 + new = get_value_in_direction(grid,(nr,nc),d,length,'list') + + if int(max(new)) >= int(cur): + test[d] = 'hidden' + else: + test[d] = 'visible' + # while notVisible: + # print((r,c),d,(nr,nc)) + # new = get_value_in_direction(grid,(nr,nc),d) + # #print(new,(nr,nc)) + # if new is not None: + # if cur > int(new) : + # print(cur,'>',new) + # notVisible = False + # (nr,nc) = addTuples((nr,nc),directions[d]) + # if not grid_valid(nr,nc,grid): + # break + # nprint(grid,(r,c),str(cur),positions=visible) + # input() + #if not notVisible: + # visible.append((r,c)) + + #print((r,c),test) + #nprint(grid,(r,c),cur) + if 'visible' in test.values(): + visible.append((r,c)) + #print(x) + #input() + nprint(grid,positions=visible) + return len(visible) + +start_time = time.time() +#print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms') + + +######################################### +# # +# Part 2 # +# # +######################################### +def part2(): + grid = toGrid(input_f) + nprint(grid) + + directions = { + 'up': (-1, 0), + 'down': (1, 0), + 'left': (0, -1), + 'right': (0, 1), + } + + visible = [] + for r,row in enumerate(grid): + for c,col in enumerate(row): + if r == 0 or r == len(grid)-1 or c == 0 or c == len(row)-1: + visible.append((r,c)) + else: + #print(r,c) + cur = get_value_in_direction(grid,(r,c)) + + x = [] + test = {} + length = 0 + score = 0 + view_distance = 0 + notVisible = False + (nr,nc) = (r,c) + print((r,c),cur) + for d in directions.keys(): + #print(d) + if d == 'up': + length = r + if d == 'down': + length = len(grid)-r-1 + if d == 'left': + length = c + if d == 'right': + length = len(row)-c-1 + new = get_value_in_direction(grid,(nr,nc),d,length,'list') + print('->>>',new) + if isinstance(new,list): + for idx,i in enumerate(new): + if int(i) >= int(cur): + print(i,cur,idx) + view_distance = (idx+1) + + else: + if int(new) <= int(cur): + print(new,cur,1) + view_distance = +1 + print('View distance',view_distance,d,'<---') + #if int(max(new)) >= int(cur): + # test[d] = 'hidden' + #else: + # test[d] = 'visible' + nprint(grid,(r,c),cur) + input() + if 'visible' in test.values(): + visible.append((r,c)) + + nprint(grid,positions=visible) + return len(visible) + +start_time = time.time() +print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms') \ No newline at end of file diff --git a/2022/day8/day8_part1.py b/2022/day8/day8_part1.py index 28908e3..540f179 100644 --- a/2022/day8/day8_part1.py +++ b/2022/day8/day8_part1.py @@ -2,7 +2,7 @@ import sys from pprint import pprint -with open(sys.argv[1],'r') as f: +with open('test_input','r') as f: lines = [[tree for tree in lines.rstrip('\n')] for lines in f] diff --git a/2024/14/14.md b/2024/14/14.md new file mode 100644 index 0000000..c2357e1 --- /dev/null +++ b/2024/14/14.md @@ -0,0 +1,177 @@ +## \-\-- Day 14: Restroom Redoubt \-\-- + +One of The Historians needs to use the bathroom; fortunately, you know +there\'s a bathroom near an unvisited location on their list, and so +you\'re all quickly teleported directly to the lobby of Easter Bunny +Headquarters. + +Unfortunately, EBHQ seems to have \"improved\" bathroom security *again* +after your last [visit](/2016/day/2). The area outside the bathroom is +swarming with robots! + +To get The Historian safely to the bathroom, you\'ll need a way to +predict where the robots will be in the future. Fortunately, they all +seem to be moving on the tile floor in predictable *straight lines*. + +You make a list (your puzzle input) of all of the robots\' current +*positions* (`p`) and *velocities* (`v`), one robot per line. For +example: + + p=0,4 v=3,-3 + p=6,3 v=-1,-3 + p=10,3 v=-1,2 + p=2,0 v=2,-1 + p=0,0 v=1,3 + p=3,0 v=-2,-2 + p=7,6 v=-1,-3 + p=3,0 v=-1,-2 + p=9,3 v=2,3 + p=7,3 v=-1,2 + p=2,4 v=2,-3 + p=9,5 v=-3,-3 + +Each robot\'s position is given as `p=x,y` where `x` represents the +number of tiles the robot is from the left wall and `y` represents the +number of tiles from the top wall (when viewed from above). So, a +position of `p=0,0` means the robot is all the way in the top-left +corner. + +Each robot\'s velocity is given as `v=x,y` where `x` and `y` are given +in *tiles per second*. Positive `x` means the robot is moving to the +*right*, and positive `y` means the robot is moving *down*. So, a +velocity of `v=1,-2` means that each second, the robot moves `1` tile to +the right and `2` tiles up. + +The robots outside the actual bathroom are in a space which is `101` +tiles wide and `103` tiles tall (when viewed from above). However, in +this example, the robots are in a space which is only `11` tiles wide +and `7` tiles tall. + +The robots are good at navigating over/under each other (due to a +combination of springs, extendable legs, and quadcopters), so they can +share the same tile and don\'t interact with each other. Visually, the +number of robots on each tile in this example looks like this: + + 1.12....... + ........... + ........... + ......11.11 + 1.1........ + .........1. + .......1... + +These robots have a unique feature for maximum bathroom security: they +can *teleport*. When a robot would run into an edge of the space +they\'re in, they instead *teleport to the other side*, effectively +wrapping around the edges. Here is what robot `p=2,4 v=2,-3` does for +the first few seconds: + + Initial state: + ........... + ........... + ........... + ........... + ..1........ + ........... + ........... + + After 1 second: + ........... + ....1...... + ........... + ........... + ........... + ........... + ........... + + After 2 seconds: + ........... + ........... + ........... + ........... + ........... + ......1.... + ........... + + After 3 seconds: + ........... + ........... + ........1.. + ........... + ........... + ........... + ........... + + After 4 seconds: + ........... + ........... + ........... + ........... + ........... + ........... + ..........1 + + After 5 seconds: + ........... + ........... + ........... + .1......... + ........... + ........... + ........... + +The Historian can\'t wait much longer, so you don\'t have to simulate +the robots for very long. Where will the robots be after `100` seconds? + +In the above example, the number of robots on each tile after 100 +seconds has elapsed looks like this: + + ......2..1. + ........... + 1.......... + .11........ + .....1..... + ...12...... + .1....1.... + +To determine the safest area, count the *number of robots in each +quadrant* after 100 seconds. Robots that are exactly in the middle +(horizontally or vertically) don\'t count as being in any quadrant, so +the only relevant robots are: + + ..... 2..1. + ..... ..... + 1.... ..... + + ..... ..... + ...12 ..... + .1... 1.... + +In this example, the quadrants contain `1`, `3`, `4`, and `1` robot. +Multiplying these together gives a total *safety factor* of `12`. + +Predict the motion of the robots in your list within a space which is +`101` tiles wide and `103` tiles tall. *What will the safety factor be +after exactly 100 seconds have elapsed?* + +Your puzzle answer was `230686500`. + +The first half of this puzzle is complete! It provides one gold star: \* + +## \-\-- Part Two \-\-- {#part2} + +During the bathroom break, someone notices that these robots seem +awfully similar to ones built and used at the North Pole. If they\'re +the same type of robots, they should have a hard-coded [Easter +egg]{title="This puzzle was originally going to be about the motion of space rocks in a fictitious arcade game called Meteoroids, but we just had an arcade puzzle."}: +very rarely, most of the robots should arrange themselves into *a +picture of a Christmas tree*. + +*What is the fewest number of seconds that must elapse for the robots to +display the Easter egg?* + +Answer: + +Although it hasn\'t changed, you can still [get your puzzle +input](14/input). + diff --git a/2024/14/solution.py b/2024/14/solution.py new file mode 100644 index 0000000..eb7742a --- /dev/null +++ b/2024/14/solution.py @@ -0,0 +1,135 @@ +#!/bin/python3 +import sys,time,re +from pprint import pprint +sys.path.insert(0, '../../') +from fred import list2int,get_re,lprint,loadFile,addTuples,grid_valid +start_time = time.time() + +# input_f = 'test' +# size_r = 7 +# size_c = 11 + +input_f = 'input' +size_r = 103 +size_c = 101 + +grid = [['.']*size_c]*size_r + +def nprint(grid,pos,x): + for r in range(size_r): + for c in range(size_c): + if (c,r) == pos: + print(x,end='') + else: + print(grid[r][c],end='') + print() + +######################################### +# # +# Part 1 # +# # +######################################### +def part1(): + instructions = loadFile(input_f) + for idx,inst in enumerate(instructions): + match = get_re(r"^p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)",inst) + + instructions[idx] = [(int(match.group(1)),int(match.group(2))),(int(match.group(3)),int(match.group(4)))] + + coordinates = {} + initial = {} + for idx,inst in enumerate(instructions): + #inst = [(2,4),(2,-3)] + #print(inst) + + #print('Initial state') + pos = inst[0] + vel = inst[1] + if pos not in initial: + initial[pos] = 0 + initial[pos] += 1 + + #nprint(grid,pos,'1') + length = 100 + for i in range (0,length): + pos = addTuples(pos,vel) + #print('After',i+1,'seconds') + if pos[0] < 0: + pos = (pos[0]+size_c,pos[1]) + if pos[0] >= size_c: + pos = (pos[0]-size_c,pos[1]) + if pos[1] < 0: + pos = (pos[0],pos[1]+size_r) + if pos[1] >= size_r: + pos = (pos[0],pos[1]-size_r) + + #print('Position inside grid: ', grid_valid(pos[1],pos[0],grid)) + #nprint(grid,pos,'1') + #print(pos) + #input() + if pos not in coordinates: + coordinates[pos] = 0 + coordinates[pos] += 1 + #print('End State') + #nprint(grid,pos,'1') + #input() + + #pprint(coordinates) + # print(instructions) + # print() + # print(initial) + # print() + # for r in range(size_r): + # for c in range(size_c): + # if (c,r) in initial.keys(): + # print(initial[(c,r)],end='') + # else: + # print(grid[r][c],end='') + # print() + # print('----------------------') + # print(coordinates) + + # for r in range(size_r): + # for c in range(size_c): + # if (c,r) in coordinates.keys(): + # print(coordinates[(c,r)],end='') + # else: + # print(grid[r][c],end='') + # print() + + center = (int((size_r-1)/2),int((size_c-1)/2)) + + TL = 0 #top left + BL = 0 #bottom left + TR = 0 #top right + BR = 0 #bottom right + for v in coordinates: + if v[0] < center[1] and v[1] < center[0]: + #print(v,'top left',coordinates[v]) + TL += coordinates[v] + if v[0] > center[1] and v[1] < center[0]: + #print(v,'top right',coordinates[v]) + TR += coordinates[v] + if v[0] > center[1] and v[1] > center[0]: + #print(v,'bot right',coordinates[v]) + BR += coordinates[v] + if v[0] < center[1] and v[1] > center[0]: + #print(v,'bot left',coordinates[v]) + BL += coordinates[v] + + #print(center) + return TL*TR*BR*BL +start_time = time.time() +print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms') + + +######################################### +# # +# Part 2 # +# # +######################################### +def part2(): + return + +start_time = time.time() +print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms') \ No newline at end of file diff --git a/__pycache__/fred.cpython-311.pyc b/__pycache__/fred.cpython-311.pyc index a2efa71b2965bd2ba11d8b08ddf0d8c65ba42a57..7a21d98d5a754bcb4d83aed72d35b57993371f11 100644 GIT binary patch delta 3990 zcma)9Yiv}<6~1@xK5efJ-o;+8U+cHmvDfbU5n~gcjsp%_+W`WY7_;8FHjCH0%iL=x zq$Y-7wU8pkWKz{_Au%oCA@ajyQ<^quRUtKL)r8osqqGqeQ3MMtmK}Xbqy%Q=ky4P!Cq7aRTkseJxqx^t zih^(ze)`iVk_s3rB&FgG!CU=L6pTcIy%Cw_AQ!zulM%8IQV{G2sce60cI9d$(-9m13aa$*hw^Wm)z~vMOlT?a z8xrrNP8pM3D9m-a*#SppSsC`r5xfA31ON*3=|<(nV4PL~Ygghe$Ge8LI9W5PLvdK1 z8|W(rS`7`Y0Z>uvu%1|S?$`pzXMOCk) z8GJP~pU(i8-{mptWWj8o_%<8QZhQ*$d5v_LeSo1!imZA?T7zCCna#WQmm0{@a8x^r8)Tc?I zA*vabaDP;@#bZjCpX!hih87+?j(86Kl@9nLVMIJ$%Z*39AAyd2ndpK%5YEsdN^UsKB<&+ko`!<&| zAGM4aN6dYO5pe+bF3^x_XESDZIWZ0J1=AWeZ9xsJ!9dJ-vh`;~7%{TZ^%5k>c_2S1thuVxxg@T}JiJ2qlGvS;EH+-{W_|ltvs~Zg z=*w9h3nAwj90Co!vM0!O`Sc`+-q3_Aq9(~vq8WQ5L-Iq>qe)P1yf!^K)q@C+e@IR$ z<+)t5$*QA2Rw|5Dx-qQkcA?iD6ATgzX^(W1b)3#ZzpK z>ZxQHM!trhau&kO2w_LgB`X|Zd+6&<+=|XgB*GyjXY+m#4 zq-j^njH_kV)dB>(_guLXWU}^b__B01I#o37YM5~~%(@zYfcKs=Yod5U@tyTfZaM3_ z9GZ6eXPo|7rymG-Z&~f9ET=6eEvGCG@?q_K1Jsw;SM!>G{xGsJq`~a`zCn?pAgBmK0FM?SOFXW}@AqKv1y;OnGMSeXe$^;ppRZeI zXfU$;wZTO6sS}1(#4#cf2PQ^69VPy~;Tz-su2uG@eQU-Z; zwd}90w4alhk16*wS{steQa!~m(yyH;q!|a~BZ_9C!Dzp%-$A$Ij8r|Nd>@5RBAh~a z4S_qShD|-wV&<`z!EQgDkxb9Q*kQ1g@?j!->s`@aFwr{sogZ(VahA+FOPI0krXG$G zJ5b|H+;97vCwOMJutnK$Z9zGq-!eKsD|DEVS+wf&L7dMIl_o1@_(c0&$w1 zYcH~(%LDXv_DQ=ZHyLQnLS?v&E3!9*ZpOYzQG-;a5oYXo)ydavCE-H@kXVEC7a;Ia z;wK$-BAnLGJ8zi8>+Fr)gRbkqr;`8y?wFn2+^zHjmboX;$#3l&QQ}R6p8{wS+=ewX zl?P++?eoaS>xF&`{~=P`@NHZa&XOMLX?%h7D!aa?LcGTA>?sr9XSThbas}j+G=PPC zJ>Tj#Q)%ap4*D^S-cNMyEjMt>(#gc=z8g{=`X3I~MrbrC9*gTv{S|WU@S&cbefIZp z%tYk4dXQdYpY(XrxKX6uK85}T#;Oxv_oR!X{3!A8mI8r*R|;?&1R(U#I00`F)TSc} zJq8_m2|%-jA%m!~SVZA_*KE)og<6EV}NMYvX`H!b5idlijCHFEnnC=a!N?aOk;3Do^Ya4APtApPKD6^d zE}s^t1u)JBeIG4^nF{GTz;!f8izd_}TCC;+yJS-7E2gEuD4}J5rL-Kdj8*`a(ZMg6?FWU`u(%o+l|gG^R0XXAne}u7ZGh!hN)EM(Hoid|jvMgWPn6Im;Q1*z;s`YV z8HwQlv9gkxDjQ815hIq+bTdVCxvH%t6vBU$sWg-vvpn%cgzk^URaOY2oTgj(rA#vT zLr;5&4+vJ)P(nMSGGibf(+ySyr1fUVo2BekpvhbaZUhfNz+-uaBJp@+5Y&|;)r)|B zVI>He2w4c(d@QGYLmoEs5efiw)aDlt6LY(a#M3NBSv}CVm_N+9cLTv9BNjQcY&d?X zDnM@Yv8uhKnZH~0xh!EcCyfmmtd#$|s;#yiM%f-*X)+g0vY2MDL%^LgkNV#u!7gY9 z(k4C(?Nt_X#clZ>VBF=qYeKN7c+Eqpc4=GS9kD=}CC;uK$_{W^UrQeFsroIj#`o&C z6`(U&5CNkvps+gbZfJbsi_pxZU7M+%OGY$0FpQxV0p3qg=oj1{+{#~Vcnww& zY&;=V90e*nhVU%%SL_s~|4yL#*aGsNLl7?Q!`5*G6b0`*k8QE8GHl`Ez&myD5#C9M zsCQU3o>DbKWsCyr54=2>XhemUJd|RVQ;!X6Lm1SH4`v_s{~<~I2f-_n;pO+AEX(O| zJpcM}nEAYX-U+1KW9!Q&L|-}Y8kfhFs5DMSaAgj5)X3y-hs!3YbHphK8;xxI+RwN| z6uWt`-_xCGHi)9*n2HeP`K^UP^n-}1#kg{5c04m+dnv$owKQ5}8BQx>Y_=3aj1ug*pW9zfeT&|mY>V9F< zgTkf{3!9(;|4;JPP1DP5v#~jOR=ZYvKQHtkFZ5wv2paJJ*pvOT`;vPKeha?EIYeyo zldd9DZaYodi(p-l97`FN-u5U|NeohmPb`Nk;y}p29340li9@DhbT#m&mTMezEEil_r4@~#%23zU`{{z$oc<^*69PGk{ADr zOR#A1-_`XsGpu<~uSIx>ct{suIGPfSuBm~bj(myF9Y7oW=0I0i9EQTZl6^Y9VrxT^ zSUqS)l7PjwIQt}fb7^^@XA{>t*@S3{(_i=)tsL;Ki5>gmfkKvZL><#Dg+;Vs)xL#1 zgClb6+o<#UE!dDQM4u8v?h(_W3)GdjggLlkQG?fo@Z6H2=sjDLYn;<<5w$n}6 z&IQM(4g6$7$ox~++eB%YIXHWe&wt^4$P0Gx@3K#vSxzlM)g_DZv)#?)$Nan90Wj7F z-J43$($^jADtwlNa6xmttf!j%l<(@Pb)(zE>=hpE@vqN-w&i9jT+MVfkj2`uujodE z8SDi<-*d50B#ei~UKoKQ7GbwR;EuWD$Yuh|(t7VH36PvKee)0<%s4ONNZH!#!6lkiE%| z_6NyZ{6c>txy7&b`0JESR~5PU$YFL5xW6|S`kN$|2>dH%<%xT8rHB+K z!_`@GGLf_${0?*j*)Y++BK_I7kf%^JX`Etj@#vsGR~SVejOy$I;MJR78!R9bLaQC> z;c!3>3loGPBGESCKs6i#V>%m$4x2}f-WZe-Baw*f_SW&@EN;f)qACifZ4SI>GI5&V zossQ8*oT1D5%(enaXbNmItbcW4^krt6hYXXVJn4z^-k0#b`e_`fWoQ5KDHxpPwaIB zu_fH>W6!S91Wm=&J?z)eg@|?NeGsw>G9lz6hwr|_$M4dO<|A578Y>ALL;%x6;&V+F PpS7@$KOOx@)W-h+gHZUk diff --git a/fred.py b/fred.py index fc21341..341f442 100644 --- a/fred.py +++ b/fred.py @@ -1,5 +1,6 @@ import sys,re,heapq from itertools import permutations +from termcolor import colored def loadFile(input_f): """ @@ -242,7 +243,7 @@ def getCenter(grid): return (int(len(grid) / 2), int(len(grid[0]) / 2)) -def nprint(grid, cur: set = None, sign: str = None): +def nprint(grid, cur: set = None, sign: str = None, positions:list = None): """ Prints a grid, highlighting the current position if specified. @@ -251,7 +252,8 @@ def nprint(grid, cur: set = None, sign: str = None): cur (set, optional): A set containing the (row, col) indices of the current position. Defaults to None. sign (str, optional): The sign to highlight the current position with. Defaults to None. - + positions (list, optional): A list of sets containing the (row, col) indices of positions to color. + Defaults to None. Returns: None @@ -262,6 +264,8 @@ def nprint(grid, cur: set = None, sign: str = None): raise TypeError("Cur must be a tuple with (row, column) indices.") if sign is not None and not isinstance(sign, str): raise TypeError("Sign must be a string.") + if positions is not None and not isinstance(positions, list): + raise TypeError("Positions must be a list.") for idx, i in enumerate(grid): for jdx, j in enumerate(i): @@ -269,9 +273,15 @@ def nprint(grid, cur: set = None, sign: str = None): if len(sign) > 1: print(sign[0] + grid[idx][jdx] + sign[1], end='') # Print with sign else: - print(sign, end=' ') # Print sign + print(colored(sign,'blue'), end=' ') # Print sign else: - print(grid[idx][jdx], end=' ') # Regular grid element + if positions is not None: + if (idx,jdx) in positions: + print(colored(grid[idx][jdx],'red'),end=' ') + else: + print(grid[idx][jdx], end=' ') + else: + print(grid[idx][jdx], end=' ') # Regular grid element print() def list2int(x): @@ -417,7 +427,7 @@ def get_value_in_direction(grid:list, position:set, direction:str=None, length:i else: return None else: - for step in range(length): + for step in range(1,length+1): new_x, new_y = x + step * dx, y + step * dy # Check for out-of-bounds if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[new_x]):