pb , 359 octets
^w[B!0]{w[B=10]{t[T+1]b[0]}>}<w[T!0]{w[B!0]{<}>^b[T]vw[B!0]{t[B]b[0]^v[B]v<[X]w[B!0]{>}b[T]<[X]^[Y+2]w[B=0]{>}t[B]b[0]>b[T]v}^t[B-1]vw[B=0]{<}}>b[10]t[X]w[X!-2]{w[B!0]{v}<}w[X!T]{b[35]>}^[Y]^<[X]w[B!10]{t[B]b[0]w[T=35]{t[10]}v<[X]w[B!35]{w[B=0]{v<[X]<b[1]}>}b[T]^[Y]^<[X]w[B=0]{>}}<[X+2]w[B=0]{v}w[B!0]{b[0]>}w[Y!-1]{<[X]^w[B!0]{w[B=35]{b[0]}w[B=10]{b[35]}>}}
En pb, l'entrée est strictement unidimensionnelle. Il ne comprend pas que vous dessinez une forme avec votre entrée, il ne voit qu'une longue ligne avec quelques octets d'une valeur de 10. La première chose que ce programme fait est de copier tout sauf la première "ligne" d'entrée sur Y = 0, Y = 1, etc., pour créer la forme du moule.
Quelque chose que j'ai beaucoup remarqué dans le golf de code, mais surtout lorsque vous jouez aux langages ésotériques, c'est que vous ne voulez souvent pas avoir deux branches à gérer; vous vous préparez simplement à faire la même chose dans les deux cas. La manière naïve de résoudre ce problème serait probablement de vérifier la longueur de la chaîne par rapport au nombre de hachages dans le reste de l'entrée et de faire quelque chose en fonction du résultat, car elle doit se comporter différemment selon ce qui est coupé. Mais cela fait beaucoup d'octets.
Au lieu de cela, après avoir terminé le moule, une ligne supplémentaire est ajoutée au bas. Il s'agit simplement de n
hachages consécutifs, où n
est la longueur de la chaîne. Maintenant, la chaîne est garantie pour s'adapter! Après avoir inséré tous les caractères de la chaîne, cette ligne supplémentaire qui a été ajoutée est détruite inconditionnellement. Tous les hachages restants dans le moule proprement dit sont également effacés, et c'est la sortie nécessaire!
Bien sûr, cela violerait la spécification pour simplement détruire tous les hachages. Après tout, il pourrait y avoir un hachage dans la chaîne d'entrée! Pour gérer cela, je me réfère à une autre partie de la spécification:
Vous obtenez une seule chaîne ASCII imprimable ne contenant aucune nouvelle ligne
(Je souligne.) Au moment où nous traitons la chaîne, nous ne nous soucions pas vraiment de la présence de nouvelles lignes, mais nous savons qu'il n'y en a pas. Ainsi, tous les hachages sont remplacés par des nouvelles lignes avant d'être mis dans le moule! Une fois tous les hachages détruits, toutes les nouvelles lignes sont à nouveau remplacées par des hachages. Cela ne transforme pas la sortie entière en une seule ligne délimitée par des hachages car la nature de la sortie 2D de pb signifie qu'il n'a jamais réellement mis de nouvelle ligne à la fin de chaque ligne, il est simplement passé à la ligne suivante.
Non golfé:
# Start by copying down the mold
^
# (B means "the character under the cursor")
w[B!0]{ # While B isn't a null byte:
w[B=10]{ # While B IS a newline:
t[T+1] # Increase T by 1
# (`T` is the only variable that can be modified directly)
b[0] # Overwrite with 0 to break out of inner loop
}
> # Move to the right
# (dodge the 0 we wrote and progress towards the end of input)
}
# Brush is now at the end of the input, T contains number of lines
< # Make sure the brush is actually /on/ the input
w[T!0]{ # While T isn't 0:
w[B!0]{<}> # Go to the first character of the last line
^b[T] # Place a flag above current character
# Also a convenient way to get the value of T back later
vw[B!0]{ # While the character under the flag isn't 0:
t[B]b[0] # Put it in T, overwrite with 0
^v[B]v # Go down by the amount written in the space above
<[X] # Go left by the amount right the brush is (i.e. go to X=0)
w[B!0]{>} # Find first empty space
b[T] # Write the value of T
<[X] # Go left by the amount right the brush is
^[Y+2] # Go up by the amount down the brush is plus 2 (above input)
w[B=0]{>} # Find flag
t[B]b[0] # Pick it up, overwrite with 0
>b[T] # Place it to the right
v}
^t[B-1]v # Collect flag - 1
w[B=0]{<} # Go to end of previous line
}
# Mold is placed, all that's left is placing the string
>b[10] # Put a newline at the end, guaranteed to not be in the string
t[X] # Save current X value in T
# Add more hashes, guaranteed to fit the input and findable later
w[X!-2]{ # While X!=-2:
w[B!0]{v} # Move down until hitting a null byte
< # Move left
}
w[X!T]{ # While not at the X value we saved earlier:
b[35]> # Travel right, leaving hashes
}
^[Y]^<[X] # Go to (0, -1)
w[B!10]{ # Until hitting the newline at the end:
t[B]b[0] # Pick up character, overwrite with 0
w[T=35]{ # If it's a hash...
t[10] # Make it a newline so we remember, deal with it later
}
v<[X] # Go to (0, 0)
w[B!35]{ # While B is not a hash:
w[B=0]{ # While B IS null:
v # Go down
<[X]< # Go to X=-1
b[1] # Print a 1 to break loop (it won't be rendered anyway)
}
> # Go right, either ignore a non hash or go to X=0
}
b[T] # Overwrite hash with picked up character
^[Y]^<[X] # Go to (0, -1)
w[B=0]{>} # Go to first character of it to restart loop
}
<[X+2] # Go to (-2, -1)
w[B=0]{v} # Go down until finding the row of added hashes
w[B!0]{b[0]>} # Wipe it out unconditionally
w[Y!-1]{ # For every remaining line on the screen:
<[X]^ # Go to the beginning
w[B!0]{ # For each character in it:
w[B=35]{ # If it's a hash:
b[0] # Destroy it
}
w[B=10]{ # If it's a newline:
b[35] # Write a hash (after the check to destroy hashes!)
}
>}
}