En citant cette question sur SO (alerte spoiler!):
Cette question a été posée dans une interview avec Oracle.
Comment diviseriez-vous un nombre par 3 sans utiliser *, /, +, -,%, opérateurs?
Le numéro peut être signé ou non signé.
La tâche peut être résolue, mais voyez si vous pouvez écrire le code le plus court.
Règles:
- Effectuer la division entière requise (
/3
) - Ne pas utiliser les opérateurs non basés sur le texte
*
,/
,+
,-
ou%
(ou leurs équivalents, par exemple__div__
ouadd()
). Ceci s'applique également aux opérateurs d'incrémentation et de décrémentation, tels quei++
oui--
. L'utilisation d'opérateurs pour la concaténation de chaînes et le formatage est correcte. L'utilisation de ces caractères pour différents opérateurs, tels que l'-
opérateur unaire pour les nombres négatifs, ou*
pour représenter un pointeur en C est également acceptable. - La valeur d'entrée peut être arbitrairement grande (tout ce que votre système peut gérer), à la fois positive et négative
- L'entrée peut être sur STDIN ou ARGV ou entrée d'une autre manière
- Créez le code le plus court possible pour faire ce qui précède
Réponses:
J,
45 4410 caractères".,&'r3'":
Fonctionne avec des négatifs:
":
- formater en texte,&'r3'
- ajouterr3
à la fin".
- exécuter la chaîne, par exemple15r3
la source
3 3 3 #: 9
. Il semble que vous ayez besoin de savoir combien de temps votre numéro ternaire sera._3]\i.
est également un point de départ possible pour quelque chose, mais je ne sais pas si ce serait plus court que votre solution ici. Le problème avec#_3]\i.
ce qu'il est, c'est qu'il arrondit toujours au lieu de tomber.##~3=_3#\i.
pour 11 personnages?##~0 0 1$~
.3#.}:(#:~$&3)
mais cela reste plus long et cela ne résout pas le problème du nombre négatif.^:
ou Agenda@.
pour un remplacementif
ou unif...else
remplacement. Dans ce cas, vous pouvez utiliser@.
deux verbes associés à un caractère '' '(un gérondif en j-speak) pour sélectionner l'un ou l'autre en fonction d'une condition.C, 167503724710
Voici ma solution au problème. J'admets qu'il est peu probable de gagner une compétition de golf au code strict, mais il n'utilise aucune astuce pour appeler indirectement la fonctionnalité de division intégrée, il est écrit en C portable (comme la question originale de Stack Overflow demandée), il fonctionne parfaitement. pour les nombres négatifs, et le code est exceptionnellement clair et explicite.
Mon programme est la sortie du script suivant:
Nombre de caractères: 71 + 39 * 2 ** 32 + 95 = 167503724710
Des repères
Il a été demandé combien de temps cela prendrait et combien de mémoire il utiliserait, alors voici quelques points de repère:
./test.py | pv --buffer-size=1M --average-rate > /dev/null
d'environ 30 secondes génère un débit d'environ 14,8 Mo / s. On peut raisonnablement supposer que le taux de sortie est à peu près constant, le temps d’exécution devrait donc être d’environ 167503724710 B / (14,8 * 1048576 B / s) ≈ 10794 s../test.py | tcc -c - -o /dev/stdout | pv --buffer-size=1M --average-rate > /dev/null
, mais il sembletcc
que rien ne soit sorti tant qu’il n’a pas lu le fichier source completla source
a[b]
est un sucre syntaxique pour*(a + b)
, qui fait l'addition.Ruby 28
Pour diviser par 3, il suffit de supprimer le zéro final en base 3:
120 -> 11110 -> 1111 -> 40
Fonctionne avec des négatifs:
Rubis,
6045Sinon, sans utiliser la conversion de base:
d = -> n {x = n.abs; r = (0..1.0 / 0) .phase (3) .take (x) .index x; n> 0? r: -r}la source
/
opérateur banni oùFloat::INFINITY
est devenu1.0/0
. Avec Ruby 2.1, on peut jouer(0..1.0/0).step(3)
au golf en0.step(p,3)
supprimant le/
. Le plus gros problème est que-r
utilise-
pour nier. Il faut 5 caractères pour passer-r
à~r.pred
, abusant d' Integer # avant de soustraire 1 sans l'opérateur de soustraction.Mathematica, 13 caractères
la source
&
et utiliser une variable simple (d’autres le font aussi).JavaScript, 56
Crée une chaîne de longueur
n
de répétition,
s et remplace,,,
par1
. Ensuite, il mesure la longueur résultante de la chaîne. (Espérons que le unaire-
est autorisé!)la source
-
opérateur de négation.-~
parparseInt()
-~prompt()
est supérieure àparseInt(prompt())
. Je ne sais pas comment vous allez gérer ça.alert(Array(parseInt(prompt())).slice(1).join().replace(/,,,/g,1).length)
Python,
4138xrange
semble être capable de gérer de grands nombres (je pense que la limite est la même que pour un long en C) presque instantanément.la source
10/3
égale 3, pas 4.print" -"[x<0]+
len (range (2, abs (x), 3)) `` le réduira à 39 caractèreslen()
en faire un raccourci pourrepr()
range
, car cela va créer la liste.xrange
fait semblant, alors il est capable de gérer des nombres énormes sans perdre de temps / mémoire.Haskell, 90
106Crée une liste de recherche infinie (lazy)
[(0,0),(0,0),(-1,0),(1,0),(-2,0),(2,0),(-3,-1),(3,1), ...]
, supprime tous les éléments qui ne correspondent pasn
(/=
c'est l'inégalité dans Haskell) et renvoie le premier qui le correspond.Cela devient beaucoup plus simple s'il n'y a pas de nombre négatif:
25
27renvoie simplement le
n
thème élément de la liste[0,0,0,1,1,1,2, ...]
.la source
C #, 232 octets
Mon premier code golf ... Et comme il n'y avait pas de C # et que je voulais essayer une méthode différente de celle que nous n'avions pas essayée ici, j'ai pensé tenter le coup. Comme certains autres ici, seuls les nombres non négatifs.
Ungolfed
la source
string[] g
transformant enstring[]g
.Add
?Perl (
2622)Cette version (ab) utilise le moteur de regex de Perl. Il lit un nombre en dernier argument de la ligne de commande (
pop
) et construit une chaîne de3
s de cette longueur ("3" x $number
). L'opérateur de substitution de regex (s///
écrit ici avec des délimiteurs différents en raison des règles du puzzle et d'ung
drapeau lobal) remplace trois caractères par la chaîne vide et renvoie le nombre de substitutions, qui est le nombre entier divisé par trois. Il pourrait même être écrit sans3
, mais la version ci-dessus semble plus drôle.la source
$_=3x pop;say s|333||g
.'$_=3x pop;say s|333||g||0
. Lent avec de grands nombres comme 99999999 et ne fonctionne pas avec des nombres négatifs.-p
sur la ligne de commande, et vous pouvez faire:$_=3x$_;$_=0|s|...||g
pour un total de 22, y compris la couverture des entrées 0, 1 ou 2.C, 160 caractères
Solution de division longue caractère par caractère en utilisant des tables de correspondance, c'est-à-dire sans chaîne atoi () ou printf () pour convertir entre des chaînes de base 10 et des entiers.
La sortie comprendra parfois un zéro non significatif - une partie de son charme.
Remarque:
Essai:
la source
Python 42
Puisque chaque solution postée ici que j’ai vérifiée tronque les décimales, voici ma solution.
Python
5051Puisque python fait la division du sol, voici ma solution qui implémente cela.
Le nombre entier d'entrée est dans la variable x.
Testé en Python 2.7 mais je suppose que cela fonctionne également en version 3.
la source
-3
c'est la bonne réponse-10/3
.JavaScript, 55
Si on ne peut pas utiliser
-1
, alors voici une version qui la remplace par~0
(merci Peter Taylor!).la source
~
est un opérateur Bitwise qui inverse les bits de l'opérande (le convertissant d'abord en un nombre). C'est le moyen le plus rapide de convertir une chaîne en nombre (pour autant que je sache).~~
convertit en un entier, par opposition à+
.C 83 caractères
Le nombre à diviser est passé par stdin et il le renvoie comme code de sortie de
main()
(% ERRORLEVEL% dans CMD). Ce code constitue une utilisation abusive de certaines versions de MinGW dans la mesure où, lorsque les optimisations ne sont pas activées, il traite la dernière valeur d’assignation comme une instruction return. Il peut probablement être réduit un peu. Prend en charge tous les nombres pouvant s’intégrer à unint
Si unaire nier (-) n'est pas autorisé: (129)
Si unaire nier est IS autorisé: (123)
EDIT: Ugoren m'a fait remarquer que - ~ est un incrément ...
83 caractères si la négation unaire est autorisée: D
la source
x+3
est-~-~-~x
.C, 139 caractères
Exécuter avec un nombre comme argument de ligne de commande
Essai:
Modifications:
la source
A
, ma fonction vérifie simplement le bit i du numéro n. Est-ce que C standard autorise l’omission de déclarations de type ou est-ce quelque chose de compilateur?ZSH -
3120/21Pour les nombres négatifs:
Avec des nombres négatifs (ZSH +
bc
) -6261Je ne devrais probablement pas donner ma réponse à deux programmes. Alors, voici un programme qui fonctionne pour tout signe de nombre:
Ceci utilise le même truc de conversion de base que la réponse d'Artem Ice .
la source
C,
8173 caractèresPrend en charge uniquement les nombres non négatifs.
L'idée est d'utiliser l'arithmétique de pointeur. Le nombre est lu dans le pointeur
x
, ce qui ne pointe nulle part.&x[~2]
=&x[-3]
=x-3
est utilisé pour soustraire 3. Ceci est répété tant que le nombre est supérieur à 2.i
compte le nombre de fois que cela est fait (&i[1]
=i+1
).la source
Java
8679Supposons que l'entier est dans y:
Convertit en chaîne en base 3, supprime le dernier caractère (décalage droit ">>" en base 3), puis reconvertit en entier.
Fonctionne pour les nombres négatifs.
Si le nombre, y, est <3 ou> -3, il donne 0.
Première publication sur code golf. =) Donc, je ne peux pas encore commenter.
Thx Kevin Cruijssen pour les conseils.
la source
&&
à&
et 2xInteger
àLong
. (Aussi, pourquoi utilisez-vous~2
au lieu de juste-3
? Ce sont le même nombre d'octets.)-
, mais je ne sais pas si cela compte pour la négation unaire.Python2.6 (
29) (71) (57) (52) (43)Edit - Je viens de me rendre compte que nous devons aussi gérer les entiers négatifs. Va réparer ça plus tard
Edit2 - Fixe
Edit3 - Sauvegardé 5 caractères en suivant les conseils de Joel Cornett
Edit4 - Etant donné que l'entrée ne doit pas nécessairement provenir de STDIN ou d'ARGV, enregistrez 9 caractères en ne prenant aucune entrée de stdin
la source
abs()
print z if x==abs(x) else -z
print (z,-z)[x<0]
Javascript,
4729Utilise
eval
pour générer dynamiquement a/
. Utilisé+
uniquement pour la concaténation de chaînes, pas pour l'addition.EDIT: Utilisé
"\57"
au lieu deString.fromCharCode(47)
la source
alert(eval(prompt()+"\573"))
?Rubis (
432217)Non seulement le golf, mais l'élégance aussi :)
La sortie sera comme
(41/1)
. Si ce doit être un entier, nous devons ajouter.to_i
au résultat, et si nous passonsto_i
à,to_f
nous obtiendrons également une sortie pour les floats.la source
rational
ligne require sur Ruby 1.9.3. L'omission des parenthèses enregistre un caractère supplémentaire .TI-Basic, 8 octets
Gagnant? :)
PS arrondit vers l'infini pour les nombres négatifs (voir ici pourquoi). Pour arrondir à zéro à la place, remplacez-le
int(
pariPart(
aucun changement d'octet.Cas de test
la source
Python 2.x,
545351print' -'[x<0],len(range(*(2,-2,x,x,3,-3)[x<0::2]))
Où
_
est le dividende et est inscrit comme tel.Remarque: Vous ne savez pas si l'utilisation de l'interpréteur interactif est autorisée, mais selon l'OP: "L'entrée peut être sur STDIN ou ARGV ou être entrée de toute autre manière"
Edit: Maintenant pour python 3 (fonctionne en 2.x, mais affiche un tuple). Fonctionne avec des négatifs.
la source
__len__
suffit.len(range(100,1000))
donne900
en 3.2.3 sur linux.len(xrange(0,_,3))
est plus courte et massivement plus rapide de toute façon.C ++, 191
Avec les caractères principaux et inclus, ses 246, sans les éléments principaux et non compris, ce n’est que 178. Les nouvelles lignes comptent pour 1 caractère. Traite tous les nombres comme non signés. Je ne reçois pas d'avertissement pour que main retourne un int non signé, donc c'est juste.
Ma toute première soumission de codegolf.
utilise des décalages pour diviser le nombre par 4 de manière répétée et calcule la somme (qui converge vers 1/3)
Pseudocode:
En passant, je pourrais éliminer la méthode main en nommant d main et en lui faisant prendre un caractère ** et en utilisant la valeur renvoyée par les programmes comme sortie. Il renverra le nombre d'arguments de la ligne de commande divisé par trois, arrondi au chiffre inférieur. Cela apporte sa longueur au 191 annoncé:
la source
Golfscript - 13 caractères
la source
s/seem to //
:(. Je vais devoir y réfléchirPowerShell 57 ou 46
Dans 57 caractères utilisant
%
comme opérateur PowerShell foreach, pas modulo. Cette solution peut accepter des entiers positifs ou négatifs.En 46 caractères, si
*
est autorisé en tant qu'opérateur de répétition de chaîne, ne pas multiplier. Cette option nécessite des entiers positifs en tant que valeurs d'entrée.la source
R
Ceux-ci ne fonctionnent qu'avec des entiers positifs:
Ou:
Ou:
Ou:
[[EDIT]] Et un vilain:
[[EDIT2]] Plus probablement le meilleur - inspiré du code matlab ci-dessus par Elliot G:
la source
wrong sign in 'by' argument
SmileBASIC,
585136 octets (pas de fonctions mathématiques!)Explication:
Le programme déplace le calque d'arrière-plan en douceur sur 3 images, puis obtient l'angle après 1 image lorsqu'il a parcouru 1/3 de sa distance totale.
Version de la division float, 38 octets:
Explication:
la source
Haskell
4139 caractèresFonctionne avec tous les entiers positifs et négatifs
Crée d’abord une liste de 1 ou (-1) (selon le signe de l’entrée) pour chaque troisième entier compris entre 0 et 0
n
.abs(n)
pour les nombres négatifs inclus.par exemple
n=8 -> [0,3,6]
Il retourne ensuite la somme de cette liste.
la source
Clojure, 87; fonctionne avec des négatifs; basé sur des lazyseqs
Ungolfed:
la source
Carnet de notes Sage (21)
la source