Calendrier de l'avent 🎄 (mais sans chocolats)

haha :slight_smile:

mais je crois que j’ai dĂ©finitivement sombrĂ© dans la programmation fonctionnelle, j’ai du mal maintenant avec le style impĂ©ratif que j’ai pourtant pratiquĂ© pendant des annĂ©es

aprĂšs, impĂ©ratif ou fonctionnel, je ressens le besoin (pour m’y retrouver) de dĂ©couper mon code en sous-fonctions qui font de plus petites choses

Tout pareil, mais façon recette de cuisine en impĂ©ratif
 En gĂ©nĂ©ral je pars de pseudo code en commentaire au dĂ©but, et tant que je n’ai pas de moyen simple d’implĂ©menter la ligne je fais une fonction et rebelote dedans.
Mais pour le moment je ne pense qu’en succession d’étapes, pas encore en enchaĂźnement de fonctions. Ça viendra. Dans le pire des cas l’annĂ©e prochaine je me forcerai Ă  coder en Clojure !

une vue de mon input:
ezgif.com-crop

4 « J'aime »

c’est quand mĂȘme un gros ferry

Bon Jour 10 complété. On est retombé dans du trivial je trouve. Pas de difficulté particuliÚre.

Jour 10 - Etoile 1 & 2 (Python
from datetime import datetime
import copy

def countOccupiedSeat(layout):
    count = 0
    for line in layout:
        count += line.count('#')
    return(count)

def getNbSeatOccupiedAroundNear(pos, layout):
    count = 0
    vecteurs = [(1,0), (1,-1), (1,1), (-1,0), (-1,1), (-1,-1), (0,-1), (0, 1)]

    for vecteur in vecteurs:
        testX = pos[0] + vecteur[0]
        testY = pos[1] + vecteur[1]
        if (0 <= testX < len(layout)) and (0 <= testY < len(layout[0])):
            if layout[testX][testY] == '#':
                count += 1
    return(count)

def getNbSeatOccupiedAroundFar(pos, layout):
    count = 0
    vecteurs = [(1,0), (1,-1), (1,1), (-1,0), (-1,1), (-1,-1), (0,-1), (0, 1)]

    for vecteur in vecteurs:
        testX = pos[0] + vecteur[0]
        testY = pos[1] + vecteur[1]
        while (0 <= testX < len(layout)) and (0 <= testY < len(layout[0])):
            if layout[testX][testY] == '.':
                testX += vecteur[0]
                testY += vecteur[1]
            elif layout[testX][testY] == '#':
                count += 1
                break
            else:
                break
    return(count)

def star1(layout):
    stabilized = False
    iteration = 1
    while not stabilized:
        newLayout = copy.deepcopy(layout)
        for x in range(len(layout)):
            for y in range(len(layout[0])):
                nbOccupied = getNbSeatOccupiedAroundNear((x,y), layout)
                if (layout[x][y] == "L") and (nbOccupied == 0):
                    newLayout[x][y] = '#'
                elif (layout[x][y] == "#") and (nbOccupied >= 4):
                    newLayout[x][y] = 'L'
        if newLayout == layout:
            stabilized = True
        else:
            layout = newLayout
            iteration +=1
    return(countOccupiedSeat(layout), iteration)

def star2(layout):
    stabilized = False
    iteration = 1
    while not stabilized:
        newLayout = copy.deepcopy(layout)
        for x in range(len(layout)):
            for y in range(len(layout[0])):
                nbOccupied = getNbSeatOccupiedAroundFar((x,y), layout)
                if (layout[x][y] == "L") and (nbOccupied == 0):
                    newLayout[x][y] = '#'
                elif (layout[x][y] == "#") and (nbOccupied >= 5):
                    newLayout[x][y] = 'L'
        if newLayout == layout:
            stabilized = True
        else:
            layout = newLayout
            iteration +=1
    return(countOccupiedSeat(layout), iteration)

### Debut
start_time = datetime.now()

layout = []
f = open("Z:\donnees\developpement\Python\AdventOfCode\day11.txt", "r")
for line in f:
     layout.append(list(line.rstrip("\n")))
f.close()
result, iteration = star1(layout)
print(f"star1: {result} ({iteration} iteration)")
result, iteration = star2(layout)
print(f"star2: {result} ({iteration} iteration)")

##Duration
end_time = datetime.now()
print('Duration: {}'.format(end_time - start_time))

Et le résultat :

star1: 2263 (78 iteration)
star2: 2002 (83 iteration)
Duration: 0:00:04.129776
[Finished in 4.208s]

Bon, ca m’a fait marrĂ© ce qu’a fait Ewi, du coup j’ai installĂ© Pygame et regardĂ© comment utiliser ca. C’est vachement simple en fait !
Du coup j’ai fais une visualisation pour chaque Ă©toile, que j’ai enregistrĂ© dans un gif animĂ© (via le soft ScreenToGif qui est vachement pratique).

Ca donne ca :

les gifs animés planqués

Etoile 1 :

Etoile 2:

2 « J'aime »

Je ne sais pas oĂč je suis parti avec mes fonctions gĂ©nĂ©riques ^^

Jour 11
let formatedData = data
.split('\n')
.map(d => d.split(''))

// get all surrounding positions given a position [row,col]
let surroundingPos = (pos) => (
   [[pos[0]-1,pos[1]-1], [pos[0]-1,pos[1]], [pos[0]-1,pos[1]+1],
    [pos[0]  ,pos[1]-1],                    [pos[0]  ,pos[1]+1],
    [pos[0]+1,pos[1]-1], [pos[0]+1,pos[1]], [pos[0]+1,pos[1]+1]]
)

// get all surrounding cells given a table of seats and the position from the table [row,col]
let surroundingCells = (list) => (pos) => (
    surroundingPos(pos)
    .map(p => typeof list[p[0]] !== 'undefined' ? list[p[0]][p[1]] : undefined)
    .filter(p => typeof p !== 'undefined')
)

// get first visible seat given a list, a position from the list and a direction
let firstSeatVisible = (list) => (pos) => (direction) => {
    if (typeof list[pos[0]+direction[0]] === 'undefined') return undefined
    if (typeof list[pos[0]+direction[0]][pos[1]+direction[1]] === 'undefined') return undefined
    if (list[pos[0]+direction[0]][pos[1]+direction[1]] === 'L') return [pos[0]+direction[0],pos[1]+direction[1]]
    return firstSeatVisible(list)([pos[0]+direction[0],pos[1]+direction[1]])(direction)
}

// get the positions of all the visible seats from the point of view of a given seat
let visiblePos = (list) => (pos) => (
    [[-1,-1], [-1,0], [-1,+1],
     [0,-1],          [0,+1],
     [1,-1], [+1,0], [+1,+1]]
    .map(d => firstSeatVisible(list)(pos)(d))
    .filter(p => typeof p !== 'undefined')
)

// create a table of all the visible seats from the point of view of each seat of the table
// so at a given position of this new table correspond all the visible seats 
// from the point of view of the seat at same position in first table
let cacheVisibleSeatsByPos = formatedData
.map((row,rowIndex,list) => row.map((cell,colIndex) => visiblePos(list)([rowIndex,colIndex])))

// get all the visible seats from the point of view of the seat at given pos 
// the cache is expected in this function
let visibleCellUseCache = (listVisiblePos) => (list) => (pos) => (
    listVisiblePos[pos[0]][pos[1]].map(visiblePos => list[visiblePos[0]][visiblePos[1]])
)
// same function as above but this function has already the cache and expect only the two remaining params
let visibleCell = visibleCellUseCache(cacheVisibleSeatsByPos)


// Play a round, needs the a function getSeatsFunction to know which method is used to find the seats around each seat
// If the number of occupied seat around each site is greater than the tolerance this seat will be empty
// Return the status of the table after a round is played  
let playRoundGeneric = (getSeatsFunction) => (tolerance) => (list) => (
    list
    .map((row,rowIndex, list) => (
        row.map((cell, colIndex) => {
            if (cell === '.') return cell
            
            let nbSeatsOccupied = getSeatsFunction(list)([rowIndex,colIndex]).filter(d => d === '#').length
            if (cell === 'L') {
                return nbSeatsOccupied > 0 ? 'L' : '#'
            } else {// cell === '#') {
                return nbSeatsOccupied >= tolerance ? 'L' : '#' 
            }
        })
)))

// This function plays a round, test the surrounding and have a tolerance of 4
let playRoundSurrounding = playRoundGeneric(surroundingCells)(4)
// This function plays a round, test the visible seats and have a tolerance of 5
let playRoundVisible = playRoundGeneric(visibleCell)(5)

// Play rounds until all is done, this function is generic and expect a "round" function to be given as parameter
let playUntilStableGeneric = (playFunction) => (previous) => (current) => {
    if (JSON.stringify(previous) === JSON.stringify(current)) return current
    return playUntilStableGeneric(playFunction)(current)(playFunction(current))
}

let result1 = playUntilStableGeneric(playRoundSurrounding)([])(formatedData)
let result2 = playUntilStableGeneric(playRoundVisible)([])(formatedData)

console.log(result1.map(row => row.filter(cell => cell === '#')).flat().length)
console.log(result2.map(row => row.filter(cell => cell === '#')).flat().length)

trĂšs sympa vos visualisations, merci !

1 « J'aime »

Si tu veux, j’ai fait une mega abstraction de pygame Ă  la mode « p5.js » ou « arduino »pour mes Ă©tudiants.

T’as plus qu’une fonction setup pour les paramĂštres de la fenĂȘtre et une run pour l’update.

ha bin carrement :smiley:

Et c’est reparti ! Bon courage :slight_smile:

CleanShot 2020-12-12 at 08.35.21@2x

Facile : True

2 « J'aime »

Mise Ă  part la comprĂ©hension de l’énoncĂ© dans la partie 2 (je pense pas que waypoint soit le meilleur terme, j’aurais plutĂŽt choisi vector), pas de grande difficultĂ© aujourd’hui. Ma solution en Python.

1 « J'aime »

Quelle rapiditĂ©, j’ai mĂȘme pas fini mon cafĂ© :sweat_smile:

Je bloque sur la 2eme partie alors que ca marche pour le cas de test. Je vais reprendre un café

1 « J'aime »

Pas trop difficile mais j’ai bien aimĂ© quand mĂȘme :slight_smile:

Pour la partie 2, j’ai Ă©tĂ© obligĂ© de sortir de mon canapĂ© pour prendre un papier crayon parce que je m’étais emmĂȘlĂ© les x, y dans mes rotations :slight_smile:

Part1 / Part2

tu utilises bien des valeurs absolues pour la distance de manhattan ? c’est le piĂšge bĂȘte classique :slight_smile:

On oublie Pas les balises spoiler :sweat_smile:

Est ce que quelqu’un ayant rĂ©ussi le jour 12 et ayant un peu de dispo pourrait me donner le rĂ©sultat pour ces 3 jeux de test ?
C’est pour essayer de comprendre oĂč j’ai une erreur.

Jeu de test 1

W2
N4
R90
E3
N2
W4
S5
F83
E5
F53
S3
L90
E1
S2
N2
W5
E4
L180
E4
N1
F27

Jeu de test 2

W2
N4
R90
E3
N2
W4
S5
F83
E5
F53
S3
L90
E1
S2
N2
W5
E4
L180
E4
N1
F27
L90
F9
E3
N2
N3
R90
N5
F57
W5
R180
R180
W5
F44

Jeu de test 3

W2
N4
R90
E3
N2
W4
S5
F83
E5
F53
S3
L90
E1
S2
N2
W5
E4
L180
E4
N1
F27
L90
F9
E3
N2
N3
R90
N5
F57
W5
R180
R180
W5
F44
L90
E5
F87
R180
F61
E4
F37
E2
F39
L180
F53
S1
W1
S2
E2
L90
W4
N5
E1
S1
F31
L90
W5
L180
W1
N5
R90
N5
R90
F94
S5
R90
S2
F94
S3
E1
E5
F9
L90
W5
F83
N2
N5
L90
F33
W4
L90
E5
S5
F23
W5
N1
E3
S1
N1
F59
N1
E1
S2
F56
S2
E5
R180
S4
R180
F46

Jeu 1 : 2251
Jeu 2 : 2742
Jeu 3 : 5906

Bon courage :muscle:

1 « J'aime »