I really enjoyed this one. It may also be because I was able to do it at a decent time in the day instead of near midnight...

This exercise allows me to show the advantages of 42 multiple 'for-in'; allowing to iterate on multiple collections at ones as if we where using a functional zip.

The core to the solution is to expand the line in a list of points.

I have found a couple of difficulties: at the start I did not understood that there was supposed to be diagonal lines, so my code originally looked like this:

```
method Point.List expand() = {
(x1,y1)=\p1 //extract coordinates from points
(x2,y2)=\p2
if x1==x2 return \()(
for y in Range(y1.min(y2) to=y2.max(y1)+1I) \add(\(x=x1,y=y)))
X[y1==y2] return \()(
for x in Range(x1.min(x2) to=x2.max(x1)+1I) \add(\(x=x,y=y1)))
}
```

I was saved by my assertion! 'X[y1==y2]': checking that my assumption was right: lines are either vertical or horizontal.

This is not the case, there are other kinds of lines and we just have to ignore them.

So the code became

```
method Point.List expand() = {
(x1,y1)=\p1 //extract coordinates from points
(x2,y2)=\p2
if x1==x2 return \()(
for y in Range(y1.min(y2) to=y2.max(y1)+1I) \add(\(x=x1,y=y)))
if y1==y2 return \()(
for x in Range(x1.min(x2) to=x2.max(x1)+1I) \add(\(x=x,y=y1)))
return \()
}
```

and this was passing part 1.

For part 2, I made a method to avoid repeating the Range-max pattern all over, and also to reverse the range on need to expand the diagonal lines in the right way; The final code is as follows:

```
reuse [L42.is/AdamsTowel]
Fs = Load:{reuse[L42.is/FileSystem]}
Point = Data.AddList:Data:{I x, I y }
Line = Data.AddList:Data:{
Point p1, Point p2
class method This (S that) = (
s = that.replace(S" -> " with=S",").split(S",")
ns = I.List()(for n in s \add(\(string=n)))
This(
p1=Point(x=ns.val(0I) y=ns.val(1I)),
p2=Point(x=ns.val(2I) y=ns.val(3I))
)
)
R = {class method I.List (I that, I to)=(
if that<to \()(for i in Range(that to=to+1I)\add(i))
else \()(for i in Range(to to=that+1I).reverse() \add(i))
)}
method Point.List expand() = {
(x1,y1)=\p1
(x2,y2)=\p2
if x1==x2 return \()(for y in R(y1 to=y2) \add(\(x=x1,y=y)))
if y1==y2 return \()(for x in R(x1 to=x2) \add(\(x=x,y=y1)))
return \()(for x in R(x1,to=x2), y in R(y1,to=y2)
\add(\(x=x,y=y)))
}
}
PMap = Collection.map(key=Point,val=I)
Main = (
fs = Fs.Real.#$of()
input = fs.read(\"input")
lines = Line.List()(for s in input.split(S.nl()) \add(\(s)))
map = PMap()
for l in lines, for p in l.expand() (
opt = map.val(key=p)
if opt map.put(key=p, val=opt.val()+1I)
else map.put(key=p,val=1I)
)
res=Match.Count()(for (val) in map \add(val>1I))
Debug(res)
)
```

See you tomorrow for the next one!

If you like those posts, consider checking out the main 42 website

(https://L42.is) or the youtube channel (https://www.youtube.com/MarcoServetto)

## Discussion (0)