Ça commence à devenir un tout petit peu sérieux. Aucune vraie difficulté à comprendre ou à implémenter le problème, mais on commence à sortir des trucs un peu récursifs.
En bon unixien, je considère bien sûr qu'un répertoire est un type particulier de fichier, qu'il contient toujours une vraie entrée .., et que le nom d'un fichier n'est pas une propriété intrinsèque mais simplement un nom qu'il porte dans une entrée de répertoire.
# Advent of Code 2022, day 7from__future__importannotationsimportrefromenumimportEnumfromtypingimportDict,Iterable,Iterator,Optional,TupleclassFile:def__init__(self,size:int):self.size=sizeclassRegularFile(File):def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)classDirectory(File):def__init__(self,parent:Optional[Directory]=None):ifparentisNone:# root directoryparent=selfself.files={'..':parent}# type: Dict[str, File]self._size=None# type: Optional[int]@property# https://github.com/python/mypy/issues/4125defsize(self)->int:# type: ignoreifself._sizeisNone:self._size=sum(f.sizeforname,finself.files.items()ifname!='..')# mypy does not realize self._size can no longer be Nonereturnself._size# type: ignoredefadd(self,name,f:File)->None:self.files[name]=fdefdirs(self)->Iterator[Directory]:yieldselfforname,finself.files.items():ifisinstance(f,Directory)andname!='..':yield fromf.dirs()classState:re_cd=re.compile(r'^\$ cd (.*)\n?$')re_ls=re.compile(r'^\$ ls\n?$')re_reg=re.compile(r'^(\d+) (.*)\n?$')# regular filere_dir=re.compile(r'^dir (.*)\n?$')def__init__(self,root:Directory):self.root=rootself.cwd=rootself.in_ls=Falsedefcd(self,name:str)->None:# Only 'cd /' or 'cd subdir'!ifname=='/':self.cwd=self.rootelse:target=self.cwd.files[name]ifisinstance(target,Directory):self.cwd=targetelse:raiseValueError('cannot cd to a regular file')definput(self,line:str)->None:if(m:=self.re_cd.match(line))isnotNone:self.in_ls=Falseself.cd(m.group(1))elif(m:=self.re_ls.match(line))isnotNone:self.in_ls=Trueelifself.in_lsand(m:=self.re_reg.match(line))isnotNone:size=int(m.group(1))name=m.group(2)self.cwd.add(name,RegularFile(size))elifself.in_lsand(m:=self.re_dir.match(line))isnotNone:name=m.group(1)self.cwd.add(name,Directory(parent=self.cwd))else:raiseValueError("unexpected line '{}'".format(line.rstrip()))defimport_tree(lines:Iterable[str])->Directory:root=Directory()state=State(root)forlineinlines:state.input(line)returnrootdefsolve_both(lines:Iterable[str])->Tuple[int,int]:"""Solve both parts of today's puzzle"""root=import_tree(lines)result1=sum(d.sizefordinroot.dirs()ifd.size<=100000)total=70000000# total storage spaceneeded=30000000# storage space needed for system updateused=root.size# used storage spaceavailable=total-used# currently available storage spaceto_free=needed-available# storage space to freeresult2=min(d.sizefordinroot.dirs()ifd.size>=to_free)returnresult1,result2
# En Python
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 7. Évalué à 5.
Ça commence à devenir un tout petit peu sérieux. Aucune vraie difficulté à comprendre ou à implémenter le problème, mais on commence à sortir des trucs un peu récursifs.
En bon unixien, je considère bien sûr qu'un répertoire est un type particulier de fichier, qu'il contient toujours une vraie entrée
.., et que le nom d'un fichier n'est pas une propriété intrinsèque mais simplement un nom qu'il porte dans une entrée de répertoire.