coucou
une console portable et de lâassembleur aujourdâhui ca a lâair sympa. Je regarde ça tout Ă lâheure
Ouais, plus sympa quâhier en tout cas .
Je galĂšre sur la part 2 (la part 1 est plutĂŽt facile) : je pense avoir loupĂ© la subtilitĂ© algorithmique, du coup je teste tous les chemins possibles, mais je dois avoir une couille dans le pĂątĂ©. Ce que jâai fait marche pour lâexemple mais pas pour mon input apparemment.
Edit: je mâen suis sorti : solution Python sur GitHub.
partie 1 tres facile:
Résumé
def acc(value,i,accu):
return accu+value,i+1
def jmp(value,i,accu):
return accu,i+value
def nop(value,i,accu):
return accu,i+1
def day8_1(data,i,accu):
print(data[i],accu)
if data[i][2]==1:
return accu
else :
data[i][2]+=1
accu,i=globals()[data[i][0]](data[i][1],i,accu)
return day8_1(data,i,accu)
# main
if __name__ == '__main__':
fichier = open('input.txt', 'r')
linesDeMonFichier = fichier.read().splitlines()
data = [ [i.split(" ")[0],int(i.split(" ")[1]),0] for i in linesDeMonFichier]
accu = day8_1(data,0,0)
print(accu)
Je pensai faire la mĂȘme chose⊠bonjour la complexitĂ© ^^
jâarrive Ă la partie 2, ca devient drĂŽle
Youpi jâai terminĂ© câĂ©tait finalement assez simple. Vraiment trĂšs trĂšs simple !
(je vous taquine )
Jâai testĂ© toutes les combinaisons, mais jâutilise les streams pour mâarrĂȘter dĂšs quâune solution match
avec la partie 2:
Résumé
import copy
def acc(value,i,accu):
return accu+value,i+1
def jmp(value,i,accu):
return accu,i+value
def nop(value,i,accu):
return accu,i+1
def day8_1(data,i,accu):
if data[i][2]==1:
return accu
else :
data[i][2]+=1
accu,i=globals()[data[i][0]](data[i][1],i,accu)
return day8_1(data,i,accu)
def day8_2_process(data,i,accu):
if len(data)<=i:
return accu
else :
if data[i][2] == 1:
return None
else :
data[i][2]+=1
accu,i=globals()[data[i][0]](data[i][1],i,accu)
return day8_2_process(data,i,accu)
def swap(data,i):
swapNotDone = True
while swapNotDone:
if data[i][0]=='jmp':
data[i][0]='nop'
return i+1
if data[i][0]=='nop':
data[i][0]='jmp'
return i+1
i+=1
return -1
def day8_2(data,i):
dataBackup = copy.deepcopy(data)
lastSwap = 0
lastSwap = swap(data,lastSwap)
while lastSwap != -1:
accu = day8_2_process(data,0,0)
if accu is None:
data = copy.deepcopy(dataBackup)
lastSwap = swap(data, lastSwap)
else:
return accu
return None
# main
if __name__ == '__main__':
fichier = open('input.txt', 'r')
linesDeMonFichier = fichier.read().splitlines()
data = [ [i.split(" ")[0],int(i.split(" ")[1]),0] for i in linesDeMonFichier]
accu = day8_1(data,0,0)
print('part1 :',accu)
data = [[i[0],i[1],0] for i in data]
print('part2 :',day8_2(data,0))
en mode glouton, ouais, câest tres simple si on oublie pas de faire une deepcopy pour garder un backup des instructions. Je verrai dans lâaprem si jâai le temps de faire un truc moins « con »
le coup de la deepcopy câest parce que vous utilisez pas un langage immutable. Les langages fonctionnels / immutables rendent les erreurs de ce type vraiment plus rares
Non, câest une erreur de noob . Câest juste que jâai utilisĂ© une Liste a la place dâun Tuple qui est immutables .
Choisir correctement son implĂ©mentation⊠dire que je rĂ©pĂšte ça en boucle pendant mes coursâŠ
Je me demande si le dĂ©but dâinterprĂ©teur de code Ă©crit pour le day08 sera rĂ©utilisĂ© pour les challenges suivants
Lâan dernier, il y avait un intcode computer que lâon a du enrichir de jour en jour.
Cette annĂ©e il y en a mĂȘme qui codent les solution du AOC2020 en langage intcode
Day 8 part 1 PHP
/**
* @param OutputInterface $output
*
* @return int
*/
public function day8part1(OutputInterface $output)
{
$value = 0;
preg_match_all(
'/(?P<command>jmp|acc|nop)\s(?P<action>[+|\-]\d+)/m',
$this->getFile(__FUNCTION__.'.txt', true),
$matches
);
$cursor = 0;
while (isset($matches['command'][$cursor])) {
$cursorToUnset = $cursor;
$this->{$matches['command'][$cursor]}($matches['action'][$cursor], $cursor, $value);
unset($matches['command'][$cursorToUnset]);
}
$output->write($value);
return $value > 0 ? Command::SUCCESS : Command::FAILURE;
}
/**
* @param $action
* @param $cursor
* @param $value
*/
private function jmp($action, &$cursor, &$value)
{
if ($action[0] === '-') {
$cursor -= (int)substr($action, 1);
} else {
$cursor += (int)substr($action, 1);
}
}
/**
* @param $action
* @param $cursor
* @param $value
*/
private function acc($action, &$cursor, &$value)
{
if ($action[0] === '-') {
$value -= (int)substr($action, 1);
} else {
$value += (int)substr($action, 1);
}
$cursor++;
}
/**
* @param $action
* @param $cursor
* @param $value
*/
private function nop($action, &$cursor, &$value)
{
$cursor++;
}
Et sinon une solution en mode pas glouton que je nâimplĂ©menterai pas (le mode bourrin prend 20ms je vais pas me prendre la tĂȘte) : parcourir une fois le programme sans modif, rĂ©cupĂ©rer la liste des instructions exĂ©cutĂ©es avant le premier cycle, puis ne remplacer par un nop que les instructions parcourues
Essayé :
#Si instruction executée et 'jmp' -> 'nop
data = [[i[0], i[1], 0] if i[0] != 'jmp' and i[2]==1 else ["nop", i[1], 0] for i in data]
Pas le bon résultat.
impossible, mon idée est parfaite
Day 8 part 2 PHP
/**
* @param $action
*/
private function jmp($action)
{
if ($action[0] === '-') {
$this->cursor -= (int)substr($action, 1);
} else {
$this->cursor += (int)substr($action, 1);
}
}
/**
* @param $action
*/
private function acc($action)
{
if ($action[0] === '-') {
$this->value -= (int)substr($action, 1);
} else {
$this->value += (int)substr($action, 1);
}
$this->cursor++;
}
/**
* @param $action
*/
private function nop($action)
{
$this->cursor++;
}
/**
* @param array $command
* @param array $action
*
* @return bool
*/
private function startConsole(array $command, array $action)
{
$this->cursor=0;
$this->value=0;
while (isset($command[$this->cursor]) && $this->cursor !== count($action)) {
$cursorToUnset = $this->cursor;
$this->{$command[$this->cursor]}($action[$this->cursor]);
unset($command[$cursorToUnset]);
}
return $this->cursor === count($action);
}
/**
* @param OutputInterface $output
*
* @return int
*/
public function day8part2(OutputInterface $output)
{
preg_match_all(
'/(?P<command>jmp|acc|nop)\s(?P<action>[+|\-]\d+)/m',
$this->getFile('day8part1.txt', true),
$matches
);
$originalProgram = $matches;
for($i=0; $i<count($matches['action']); $i++){
$matches = $originalProgram;
if ($matches['command'][$i]!=='acc' && (int)substr($matches['action'][$i],1)!==0)
{
$matches['command'][$i] = $matches['command'][$i]==='nop' ? 'jmp' : 'nop';
if ($this->startConsole($matches['command'], $matches['action'])) {
$output->write($this->value);
return Command::SUCCESS;
}
}
}
return Command::FAILURE;
}
Un poil bourrin aussi mĂȘme si jâai essayĂ© de virer les cas inutiles. Je me demande si en partant de la fin on ne trouve pas plus rapidement, je vais testerâŠ
je viens de coder mon optim ici : Part2
câest passĂ© de 20ms Ă 4ms
Jâai lâimpression quâune solution en partant de la fin ne marche pas : le seul cas facile Ă rĂ©glĂ© câest si on tombe Ă un moment sur un jmp -600
alors que la suite du programme ne contient que de nop et des acc, sauf que câest clairement pas le cas dans mon dataset.
Testé ton optim, bien vu !
Je passe de 246 executions Ă 55, du coup je passe de 0.020 Ă 0.006ms
Pas compris quelle instruction tu remplaces pas un nop ? Rien ne dit que tu vas pas replonger dans une branche qui ne boucle pas en changeant un jmp par nop
sur un programme de 500 instructions, au lieu de tester 500 variations oĂč je teste tour Ă tour de remplacer chacune des instructions par un nop, je vais tester seulement N variations oĂč N est le nombre dâinstructions exĂ©cutĂ©es par le programme de base.
Le diff