Tâche:
Votre programme reçoit une fraction simple appropriée et positive dans le format .<numerator>/<denominator>
Pour cette entrée, il doit trouver deux fractions.
- Une fraction inférieure à l'entrée.
- Une fraction supérieure à l'entrée.
Les deux fractions doivent avoir un dénominateur inférieur à l'entrée. De toutes les fractions possibles, elles devraient avoir la plus faible différence avec l'entrée.
Sortie:
La sortie de votre programme doit être:
- Une fraction plus petite que l'entrée, au format
<numerator>/<denominator>
. - Suivi d'un caractère espace (code ASCII 32).
- Suivi d'une fraction supérieure à l'entrée, au format
<numerator>/<denominator>
.
Comme suit:
«fraction that is < input» «fraction that is > input»
Règles:
- Toutes les fractions produites doivent être en termes les plus bas .
- Toutes les fractions produites doivent être des fractions appropriées.
- S'il n'y a pas de fractions appropriées possibles autorisées par les règles, vous devez générer
0
une entrée au lieu d'une fraction <entrée et1
au lieu d'une fraction> entrée. - Vous pouvez choisir si vous souhaitez recevoir la fraction sous forme d'argument de ligne de commande (par exemple
yourprogram.exe 2/5
) ou inviter l'utilisateur à entrer. - Vous pouvez supposer que votre programme ne recevra aucune entrée invalide.
- Le code le plus court (en octets, dans n'importe quelle langue) gagne.
Tous les arguments de ligne de commande non standard (arguments qui ne sont normalement pas requis pour exécuter un script) comptent pour le nombre total de caractères.
Ce que votre programme ne doit pas faire:
- Dépendez de toutes les ressources externes.
- Dépendre d'avoir un nom de fichier spécifique.
- Sortie autre chose que la sortie requise.
- Prenez exceptionnellement longtemps à courir. Si votre programme dure plus d'une minute pour les fractions avec un numérateur et un dénominateur à 6 chiffres (par exemple
179565/987657
) sur l'ordinateur d'un utilisateur à domicile moyen, il n'est pas valide. - Fractions de sortie avec
0
comme dénominateur. Vous ne pouvez pas diviser par zéro. - Fractions de sortie avec
0
comme numérateur. Votre programme doit sortir0
au lieu d'une fraction. - Réduisez une fraction saisie. Si la fraction donnée en entrée est réductible, vous devez utiliser la fraction telle qu'elle est entrée.
- Votre programme ne doit pas être écrit dans un langage de programmation pour lequel il n'existait pas de compilateur / interprète accessible au public avant la publication de ce défi.
Exemples:
Entrée: 2/5
Sortie: 1/3 1/2
Entrée: 1/2
Sortie: 0 1
Entrée: 5/9
Sortie: 1/2 4/7
Entrée: 1/3
Sortie: 0 1/2
Entrée: 2/4
Sortie: 1/3 2/3
Entrée: 179565/987657
Sortie: 170496/937775 128779/708320
1/3 1/2
.Réponses:
Sauge -
119117Sage n'est nécessaire que dans la dernière ligne, qui s'occupe de la sortie. Tout le reste fonctionne également en Python.
Remplacez
raw_input()
parsys.argv[1]
pour que l'entrée soit lue à partir d'un argument de ligne de commande au lieu d'une invite. Cela ne change pas le nombre de caractères. (Ne fonctionne pas en Python sans importersys
préalable.)Cela construit essentiellement récursivement les séquence de Farey utilisant des médiants des éléments existants, mais se limite aux éléments les plus proches de l'entrée. D'un autre point de vue, il exécute une recherche à intervalles imbriqués sur les séquences de Farey respectives.
Il traite correctement tous les exemples en moins d'une seconde sur ma machine.
Voici une version non golfée:
la source
exec
!Python 2.7 - 138
J'ai commencé avec la solution évidente de force brute, mais je me suis rendu compte que puisque l'OP voulait être capable de résoudre des instances avec des numérateurs et des dénominateurs à six chiffres en moins d'une minute, j'ai besoin d'une meilleure solution que d'essayer un billion de possibilités. J'ai trouvé une formule pratique sur la page Wikipedia pour la séquence de Farey: si a / b, c / d sont voisins dans l'une des séquences de Farey, avec
a/b<c/d
, alorsb*c-a*b=1
. La boucle while à l'intérieur de f dans mon programme étend ce fait aux nombres non réduits, en utilisant le gcd, que l'autre boucle while calcule.J'ai déjà joué au golf assez dur, mais j'aimerais entendre des suggestions.
Modifications:
166-> 162: Supprimé
a
etb
du programme externe. Ils n'étaient pas nécessaires.162-> 155:
str()
-> ``155-> 154: ajouté
k
.154-> 152: supprimé
x
de l'intérieur de la fonction, passé à la place comme argument.152-> 150: a donné
a
une valeur par défaut au lieu de la passer en argument.150-> 146: modification de l'initialisation de
x
ety
.146-> 145: supprimé
k
.145-> 144: Changé ... et ... ou ... en (..., ...) [...], économisant ainsi un espace.
144-> 138: changé (..., ...) [...] en ... + ... * (...). Merci à @ mbomb007.
Cas de test:
L'avant-dernier test a pris moins d'une seconde sur mon ordinateur, tandis que le dernier a pris environ 5 à 10 secondes.
la source
k=1
pure méchanceté.print`(a*n+p)/d`+('/'+`a`)*(a>1),
Mathematica, 163 octets
Ceci est sévèrement limité par l'exigence d'entrée / sortie en tant qu'entrée utilisateur et chaînes. Le traitement des cordes est vraiment compliqué dans Mathematica (au moins lorsque vous voulez jouer au golf). En faisant cela de façon naturelle dans Mathematica, (en utilisant uniquement des entiers et des rationnels), je pourrais probablement réduire cela à 50% de la taille.
Il peut faire des nombres à 6 chiffres en quelques secondes sur ma machine.
Légèrement plus lisible (mais pas vraiment non golfé):
Pour le plaisir, faire ceci "de façon naturelle", c'est-à-dire en tant que fonction prenant le numérateur et le dénominateur et retournant deux rationnels, cela ne fait que 84 caractères (donc mon estimation de 50% était en fait assez proche):
la source
Julia -
127125 octetsJe l'ai abordé d'un point de vue mathématique pour éviter d'avoir besoin de boucles, donc ce code s'exécute assez rapidement pour les grandes entrées (remarque: si a / b est l'entrée, alors a * b doit tenir dans Int64 (Int32 sur les systèmes 32 bits) , sinon des réponses absurdes sont générées - si a et b sont tous deux exprimables en Int32 (Int16 sur les systèmes 32 bits), aucun problème ne se produit).
MISE À JOUR: Il n'est plus nécessaire de surcharger la barre oblique inverse pour div, en utilisant ÷, une économie nette de 2 octets.
Non golfé:
Idée de base: trouver le plus grand d et f inférieur à b qui satisfait ad-bc = gcd (a, b) (suivant le plus petit) et be-af = gcd (a, b) (suivant le plus grand), puis calculer c et e à partir de Là. La sortie résultante est c / de / f, sauf si d ou f vaut 1, auquel cas le / d ou / f est omis.
Fait intéressant, cela signifie que le code fonctionne également pour les fractions impropres positives, tant que l'entrée n'est pas un entier (c'est-à-dire, gcd (a, b) = a).
Sur mon système, la saisie
194857602/34512958303
ne prend pas de temps perceptible pour la sortie171085289/30302433084 23772313/4210525219
la source
55552/999999
me donne-396/920632 486/936509
.int32(55552*999999)
donne-282630400
. Pour moi, avec ce test, je reçois51143/920632 52025/936509
- notez que les dénominateurs sont les mêmes, et que 52025-51143 = 486 - (- 396). J'ajouterai une note pour mentionner ce problème.1234567891234567/2145768375829475878
traduit par869253326028691/1510825213275018197 365314565205876/634943162554457681
. Cette modification ajoute seulement 3 caractères supplémentaires.JavaScript, 131
Avec notation fléchée et
eval
appels:Le
179565/987657
test de résistance est exécuté en environ 35 secondes sur Firefox, beaucoup plus sur Chrome (~ 6 minutes)Méthode plus rapide et
eval
notation sans et grosse flècheLe
179565/987657
test de résistance est exécuté en environ 5 secondes.Non golfé:
la source
eval
. EEK2/6
donne n'est1/3 2/5
cependant1/3
pas inférieur mais égal à2/6
.perl, 142 octets (155 sans CPAN)
Ou si les modules CPAN sont interdits / un code 3-4 fois plus rapide est nécessaire:
L'ancienne version prend 9,55 secondes sur ma machine, la dernière version 2,44 secondes.
Moins illisible:
la source