Ce nombre est-il triangulaire?


33

Défi

Avec un nombre entier positif, déterminez s'il s'agit d'un nombre triangulaire et indiquez en conséquence l'une de deux valeurs distinctes constantes.

Définition

Un nombre triangulaire est un nombre qui peut être exprimé par la somme d'entiers positifs consécutifs, commençant à 1. Ils peuvent également être exprimés avec la formule n(n + 1) / 2, où nest un entier positif.

Cas de test

Vérité

1
3
6
10
15
21
55
276
1540
2701
5050
7626
18915
71253
173166
222111
303031
307720
500500
998991

Fausseté:

2
4
5
7
8
9
11
16
32
50
290
555
4576
31988
187394
501500
999999

Règles

  • Votre entrée peut être une fonction ou un programme.
  • Vous pouvez supposer que l'entrée est un entier positif inférieur à 10 6 .
  • Vous devez choisir deux sorties constantes et distinctes pour distinguer les deux catégories.

C'est du , donc le code le plus court en octets dans chaque langue gagne.





Pourquoi n'avez-vous pas inclus zéro?
Neil

1
@Neil Je voulais minimiser le nombre de cas possibles et le traitement de zéro est l'un d'entre eux qui, à mon avis, n'était pas trop important. Pensez-vous qu'il aurait été préférable de traiter le zéro? (La réponse Jelly échoue actuellement à zéro, par exemple)
ETHproductions

Réponses:


21

Haskell , 23 octets

MODIFIER:

  • -1 octet: @xnor s'est débarrassé des parenthèses avec a $.

Une fonction anonyme prenant un Intet retournant un Char.

La sortie '1'concerne les nombres triangulaires et les '0'autres.

(!!)$show.(10^)=<<[0..]

Essayez-le en ligne!

  • Utiliser comme ((!!)$show.(10^)=<<[0..]) 998991.
  • Génère les nombres 1, 10, 100, 1000, ..., les convertit en chaînes et les concatène. Puis indexe dans la chaîne infinie résultante

    "1101001000100001000001000000...

6
Une méthode imaginative! Vous pouvez enregistrer un octet avec (!!)$show.(10^)=<<[0..].
xnor

20

Python , 24 octets

lambda n:(8*n+1)**.5%1>0

Essayez-le en ligne!

Sorties Falsepour les nombres triangulaires, Truepour le reste. Vérifie si 8*n+1est un carré parfait. Python prendra des carrés parfaits pour obtenir des nombres entiers exacts, quelle que soit leur taille. Il n'y a donc pas de problème de virgule flottante.


3
(1<<10000)**.5: OverflowError: int trop volumineux pour être converti en float
isaacg

@isaacg Le challenge ne nécessite pas des entrées aussi grandes: "Vous pouvez supposer que l'entrée est un entier positif inférieur à 10 ^ 6"
trichoplax

1
@trichoplax Je pense que je contestais la revendication de xnor dans le texte. La soumission est bien, je suis d'accord.
isaacg

13

Gelée , 4 octets

R+\ċ

Essayez-le en ligne!

Comment?

R+\ċ - Main link: n
R    - range(n)   -> [1,2,3,...,N]
  \  - cumulative reduce by:
 +   -   addition -> [1,3,6,...,T(N)]
   ċ - count occurrences of right (n) in left -> 1 if triangular, 0 otherwise

Je suis surpris que la réduction cumulative ne fasse pas automatiquement une plage. Y a-t-il un choix de conception derrière cela?
ETHproductions

Je ne suis pas sûr à 100%, mais je pense qu'il serait nécessaire (du moins à l'heure actuelle) de réduire le nombre d'opérations dyadiques afin de créer une plage.
Jonathan Allan

... en fait, même cela ne semble pas s'appliquer (p. ex. ceci vs ceci . Il semble que l'implémentation du lien rapide remplace telle que l'itéré ne crée pas de plage, même si l'opération dyadique le définit pour un argument. Pinged Dennis to field celui-ci :)
Jonathan Allan

@ETHproductions /et figuraient \probablement parmi les cinq premiers rapides à être implémentés, avant l’idée de convertir les arguments entiers en intervalles.
Dennis

13

Retina , 10 octets

(^1|1\1)+$

L'entrée est unaire. La sortie est0 ou 1.

Essayez-le en ligne!(En tant que suite de tests permettant une conversion décimale à unaire pour plus de commodité.)

Explication

C'est l'exercice le plus fondamental dans les références en aval. La plupart des gens connaissent les références arrières dans les expressions rationnelles, par exemple (.)\1pour faire correspondre un caractère répété. Cependant, certaines des versions les plus avancées vous permettent d’utiliser une référence arrière avant ou à l’intérieur du groupe auquel elle fait référence. Dans ce cas, cela s'appelle généralement une référence directe. Cela peut avoir un sens si la référence est répétée. Cela peut ne pas être bien défini lors de la première itération, mais lors des itérations suivantes, le dernier groupe ou le groupe environnant a capturé quelque chose et peut être réutilisé.

Ceci est le plus souvent utilisé pour implémenter des modèles récurrents sur des chaînes unaires. Dans ce cas, nous essayons de faire correspondre l'entrée avec la somme d'entiers consécutifs:

(        # This is group 1, which we'll repeat 1 or more times.
  ^1     #   Group 1 either matches a single 1 at the beginning of the string.
|        # or
  1\1    #   It matches whatever the previous iteration matched, plus another
         #   1, thereby incrementing our counter.
         # Note that the first alternative only works on the first iteration
         # due to the anchor, and the second alternative only works *after*
         # the first iteration, because only then the reference is valid.
)+
$        # Finally, we make sure that we can exactly hit the end of the
         # string with this process.

1
Pourquoi ne (^|1\1)+$fonctionne pas ?
Leaky Nun

3
Les moteurs de regex de @LeakyNun ont l'optimisation de cesser de répéter un groupe s'il était vide n fois, où n est le minimum du quantificateur que vous utilisez (dans votre cas, 1; si le minimum était 0, il serait quand même essayé une fois) . Si vous changez +à {2,}, il devrait fonctionner. Cette optimisation empêche les boucles infinies, mais c'est aussi la seule chose qui empêche les regex .NET d'être Turing-complete par eux-mêmes.
Martin Ender

Cela m'a sauvé 70 octets: codegolf.stackexchange.com/a/118387
Neil

Faites que 74 octets, grâce à \G!
Neil


8

Mathematica, 16 octets

OddQ@Sqrt[1+8#]&

Essentiellement un port de la solution Python de xnor . Sorties Truepour les nombres triangulaires, Falsesinon.


7

JavaScript (ES6), 30 27 octets

2 octets sauvés grâce à kamoroso94

f=(n,k)=>n>0?f(n+~k,-~k):!n

Cas de test

Version non récursive (ES7), 19 octets

Réponse du port d' Adnan .

x=>(8*x+1)**.5%1==0

Ne voyant que maintenant que vous avez modifié la solution de 19 octets dans votre réponse quelques minutes avant que je poste la mienne . Dois-je supprimer le mien? Quelle est l'étiquette généralement acceptée à ce sujet?
Shaggy

1
@Shaggy Je ne pense pas que ce soit un réel problème ici. Ma réponse principale est vraiment la réponse récursive.
Arnauld

Réduire à 28 octets avec f=(n,k=1)=>n>0?f(n-k,k+1):!n?
Commentaires

1
@ Kamoroso94 Merci! Mis à jour. Et un troisième octet a été enregistré en omettant l’initialisation de k.
Arnauld

Utilisation élégante de bitwise PAS comme incrémenteur pour une undefinedvaleur initiale ; votre édition était un plaisir de lire après que je suis indépendamment arrivé à votre solution précédente.
apsillers

6

CJam , 11 octets

ri2*_mQ_)*=

Sorties 1pour triangulaire, 0sinon.

Essayez-le en ligne!

Explication

Considérez l'entrée 21.

ri               e# Input integer.             STACK: 21
  2*             e# Multiply by 2.             STACK: 42
    _            e# Duplicate.                 STACK: 42, 42
     mQ          e# Integer square root.       STACK: 42, 6
       _)        e# Duplicate, increment.      STACK: 42, 6, 7
         *       e# Multiply.                  STACK: 42, 42
          =      e# Equal?                     STACK: 1

6

Brain-Flak , 40 octets

(([{}](((()))<>))<>){<>({}({}({})))}{}{}

Wheat Wizard et moi avons eu un duel sur cette question. Lorsque nous avons décidé d’afficher nos solutions, nous étions à égalité à 42 octets, mais j’ai trouvé une solution à deux octets. Nous avons décidé que cela compterait comme égalité (ma solution est ci-dessous).

Essayez-le en ligne!

Explication:

# Set up the stacks like this:  -input
                                     1     -input
                                     1          1
(([{}](((()))<>))<>)                 ^

# Output 1 for triangular and 0 for non-triangular 
{<>({}({}({})))}{}{}

Pour une explication complète, veuillez consulter la réponse de Wheat Wizard .


Brain-Flak , 42 octets

(([({})])<>){(({}())<>{}({})){((<>))}{}{}}

Les sorties 0\n(nouvelle ligne littérale) pour vérité et la chaîne vide pour fausseté.

L'idée est de soustraire 1, puis 2, puis 3, jusqu'à l'entrée. Si vous frappez 0, alors vous savez que c'est un nombre triangulaire, vous pouvez donc vous arrêter là.

Essayez-le en ligne! (vérité)
Essayez-le en ligne! (fausseté)

# Push -input on both stacks. One is a counter and the other is a running total
(([({})])<>)

# Count up from -input to 0
{
  # Push the new total which is: (counter += 1) + total (popped) + input (not popped)
  # This effectively adds 1, then 2, then 3 and so on to the running total
  (({}())<>{}({}))
  # If not 0
  {
    # Push to 0s and switch stacks to "protect" the other values
    ((<>))
  # End if
  }
  # Pop the two 0s, or empty the stack if we hit 0
  {}{}
# End loop
}

Voici une solution de 46 octets que j'ai trouvée intéressante.

{<>(({}())){({}[()]<>{(<({}[()])>)}{}<>)}{}<>}

Sorties 0\n(nouvelle ligne littérale) pour vérité, la chaîne vide pour fausseté.

L'idée est de décompter d'une entrée à la fois par numéros consécutifs, un à la fois. Par exemple input - (1) - (1,1) - (1,1,1). Chaque fois que nous soustrayons, si nous ne sommes pas encore à 0, nous laissons une valeur supplémentaire sur la pile. De cette façon, si nous sommes à 0 et que nous soustrayons toujours lorsque nous sautons, nous retirons la dernière valeur de la pile. Si l'entrée était un nombre triangulaire, nous finirons exactement à 0 et ne verrons pas le 0.

Essayez-le en ligne! vérité
essayez-le en ligne! fausseté

# Implicit input (call it I)

# Until we reach 0, or the stack is empty
{
  # Add 1 to the other stack and push it twice. This is our counter.
  <>(({}()))
  # While counter != 0
  {
    # counter -= 1
    ({}[()]
    # if I != 0 
    <>{
      # I -= 1, and push 0 to escape the if
      (<({}[()])>)
    # End if
    }
    # Pop from the stack with I. This is either the 0 from the if, or I
    {}
    # Get ready for next loop End while
    <>)
  # End While
  }
  # Pop the counter that we were subtracting from
  {}<>
# End Until we reach 0, or the stack is empty.
}

6

Gelée , 5 octets

×8‘Ʋ

Essayez-le en ligne!

Contexte

Soit n l'entrée. Si n est le k ème nombre triangulaire, on a

n=k(k+1)2k2+k2n=0k=12(1±1+8n),

ce qui signifie qu'il y aura une solution naturelle si et seulement si 1 + 8n est un carré impair et parfait. Clairement, vérifier la parité de 1 + 8n n'est pas requise.

Comment ça marche

×8‘Ʋ  Main link. Argument: n

×8     Yield 8n.
  ‘    Increment, yielding 8n + 1.
   Ʋ  Test if the result is a perfect square.


5

Brain-Flak , 42 octets

(([{}](<((())<>)>))<>){<>({}({}({})))}{}{}

Essayez-le en ligne!

Explication

Le but de ce programme est de créer un état sur deux piles et d’effectuer une opération constante sur les deux piles jusqu’à ce que l’un des zéros soit zéros, nous pouvons ensuite afficher le résultat en fonction de la pile sur laquelle nous nous trouvons. Ceci est similaire aux programmes qui déterminent le signe d’un nombre. Ces programmes mettent nsur une pile et -nsur l’autre et ajoutent un et commutent les piles jusqu’à ce que l’une des piles soit à zéro. Si le nombre était négatif en premier lieu, la première pile atteindra zéro, si le nombre était positif, l'autre pile atteindra zéro.

Ici, nous créons deux piles, une qui soustrait des nombres consécutifs de l’entrée et une autre qui en soustrait un. Celui qui soustrait des nombres consécutifs ne se terminera que si le nombre est triangulaire (sinon, il passera juste de zéro et continuera à aller dans les négatifs). L'autre se terminera toujours pour tout nombre positif, mais le sera toujours plus lentement que le premier, ainsi les nombres non triangulaires se termineront sur cette pile.

Alors, comment pouvons-nous configurer des piles de sorte que la même opération soustrait des nombres consécutifs sur l’une et soustrait l’une sur l’autre? Sur chaque pile, nous avons l'entrée en haut pour pouvoir vérifier dans, en dessous nous avons la différence et en dessous nous avons la différence de la différence. Chaque fois que nous courons, nous ajoutons la "différence de la différence" à la "différence" régulière et soustraisons celle-ci de l'entrée. Pour la pile qui vérifie la triangularité, nous définissons notre double différence de 1manière à obtenir des entiers consécutifs à chaque fois que nous exécutons. Pour l'autre pile, nous la définissons de 0manière à ne jamais changer la différence, c'est-à-dire qu'elle reste toujours 1. Voici comment la pile est mise en place au début, où se ntrouve l'entrée:

-n  -n
 0   1
 1   0

Lorsque nous terminons finalement, nous pouvons utiliser ces différences pour vérifier la pile sur laquelle nous nous trouvons. Les deux premières valeurs sont extraites et nous obtenons 1un nombre triangulaire et 0un nombre non triangulaire.


Code annoté

(([{}](<((())<>)>))<>) Set up the stack
{                      While
 <>                    Switch stacks
 ({}({}({})))          Add bottom to second to bottom, add second to bottom to top
}                      End while
{}{}                   Pop the top two values

Voici une solution de 50 octets que j'aime bien aussi.

{(({}[()]))}(([[]])<>){({}{}())<>}({}{()<><{}>}{})

Essayez-le en ligne!


5

Cubix , 23 24 25 octets

I1Wq/)s.;0..s;p-?\.+O@u

0 pour la vérité et rien 0 pour Falsey. Forces brutes en incrémentant le compteur, en ajoutant à la somme cumulative et en comparant à l'entrée. Maintenant, essayez de l’ajuster sur un cube 2x2x2. L'a fait!

    I 1
    W q
/ ) s . ; 0 . .
s ; p - ? \ . +
    O @
    u .

Essayez-le en ligne!

  • / Réfléchis pour faire face.
  • I10\ obtenir une entrée entière, appuyer sur 1 (compteur), appuyer sur 0 (somme) et réfléchir
  • +s;p-corps de boucle. Ajouter la somme et le compteur, supprimer la somme précédente, augmenter les entrées et soustraire
  • ? Tester le résultat de la soustraction
    • Pour 0 résultat continuer tout droit \.uO@ reporter à la face inférieure, non-op, demi-tour, sortie et arrêt.
    • Pour un résultat positif, tournez à droite sur la face inférieure et @ arrêtez-vous
    • Pour un résultat négatif ;qWs)/su, soustraction de gouttes à gauche , mettez l’entrée en bas, décalez à gauche, compteur et échange, somme, compteur d’incréments, réflexion, somme et compteur, demi-tour sur le corps de la boucle principale.

Si près du but… ce dernier octet demandera cependant beaucoup d'efforts et d'intelligence.
ETHproductions

Oui, je pensais l'avoir, mais je ne sais pas
trop

1
@ETHproductions a trouvé l'octet
MickyT

Votre code et votre cube déplié semblent être différents, le coin inférieur droit est un .sur le cube mais un 1dans votre code.
Wheat Wizard

@WheatWizard Merci pour cela, mauvaise édition de ma part
MickyT

4

05AB1E , 7 à 6 octets

EDIT : Merci à @Dennis: Enregistrement d’un octet car j’ai oublié l’opérateur d’incrément

8*>t.ï

Essayez-le en ligne!

nest triangulaire si sqrt(8n + 1)est un entier

Comment ça marche

8* # multiply implicit input by 8
  > # add one
   t # sqrt
    .ï # is integer

Ce n'était probablement pas encore disponible à ce moment-là, mais cela t.ïpeut être le cas de Ųnos jours, ce qui permet de vérifier si un nombre est un carré.
Kevin Cruijssen le

4

Perl 6 , 17 octets

{$_∈[\+] 1..$_}

Vérifie simplement si $_, l'entrée dans la fonction, est égale à l'un des éléments de la réduction d'addition triangulaire (1, 1+2, ..., 1+2+...+$_).


4

Alice , 38 22 octets

Beaucoup d'octets sauvés grâce à Martin et Leo

/ i \ 2 * .2RE.h * -n / o @

Il y a un retour à la ligne. Sorties 1pour triangulaire, 0sinon.

Essayez-le en ligne!

Explication

Ceci utilise la même approche que ma réponse CJam , seulement plus maladroite. Sous forme linéarisée, le programme devient

i2*.2RE.h*-no@

iet osont en réalité en mode ordinal.

Considérez l'entrée 21comme un exemple.

i         Input integer                       STACK: 21
2*        Multiply by 2                       STACK: 42
.         Duplicate                           STACK: 42, 42
2RE       Integer square root                 STACK: 42, 6
.         Duplicate                           STACK: 42, 6, 6
h         Increment                           STACK: 42, 6, 7
*         Multiply                            STACK: 42, 42
-         Subtract                            STACK: 0
n         Logical negation                    STACK: 1
o         Output integer                      STACK:
@         End program

Ma première réponse Alice
Luis Mendo

1
J'ai l'impression que cela pourrait être réduit de moitié avec l'une des structures de contrôle sophistiquées de Martin ...
ETHproductions

Moi aussi ... :-)
Luis Mendo

Mon premier golf Alice: Même code, 23 octets
Nitrodon

Une mise en page plus « standard » pour ce genre de programme serait ce . Cela dit, vous pouvez vous débarrasser du 1 de la pile et simplement afficher la négation logique de la soustraction (exemple ...h*-no@).
Léo

4

Japt , 10 7 octets

3 octets sauvegardés grâce à @Luke et @ETHproductions

*8Ä ¬v1

Essayez-le en ligne!

Explication:

*8Ä ¬v1
    ¬    // Square root of:
*8       //   Input * 8
  Ä      //   +1
     v1  // Return 1 if divisible by 1; Else, return 0

õ å+ øU

Explication:

õ å+ øU
õ           // Create a range from [1...Input]
  å+        // Cumulative reduce by addition
     øU     // Does it contain the input?

Essayez-le en ligne!


La question demande deux résultats distincts constants.
xnor

*8Ä ¬u1 cpour 9B (sortie 0 si l'entrée est triangulaire, 1 sinon)
Luc

@Luke Vous pouvez changer u1 cà v1, je crois (commutation des sorties)
ETHproductions

7 octets? Agréable! En quelque sorte, j'ai manqué cela en publiant ma propre solution similaire, la dernière en date pourrait être. Faites-moi savoir si vous souhaitez que je le supprime.
Shaggy

4

R , 23 19 octets

Approche similaire aux autres réponses. Vérifie si 8x+1c'est un carré parfait.
-4 octets merci Giuseppe et MickyT.

!(8*scan()+1)^.5%%1

Essayez-le en ligne!


2
vous pouvez utiliser !au lieu de==0
Giuseppe

C'est extra sympa car c'est aussi vectorisé!
Giuseppe

1
Je pense que vous pouvez également vous débarrasser des supports extérieurs.!(8*scan()+1)^.5%%1
MickyT

3

MATL , 5 octets

t:Ysm

Essayez-le en ligne!

Explication:

t       % Duplicate input
 :      % Range(1, input)
  Ys    % Cumulative sum. This will push the first *n* triangular numbers
    m   % ismember. Pushes true if the input is contained within the array we just pushed

J'allais poster t:Ys=a. Oublié m:-)
Luis Mendo

1
@ LuisMendo je ne savais pas mjusqu'à ce que j'ai vu cette réponse . C'est drôle comme les deux réponses sont presque identiques: D
DJMcMayhem

3

Lot, 72 octets

@set/aj=i=0
:l
@if %1% gtr %j% set/aj+=i+=1&goto l
@if %1==%j% echo 1

Sorties 1 en cas de succès, rien en cas d'échec. Fonctionne pour zéro aussi, bien que cela ne soit pas demandé par la question pour une raison quelconque.


3

JavaScript (ES7), 19 18 octets

De ma réponse à une question connexe .

Sorties falsepour les nombres triangulaires outrue pour des non triangulaires, comme le permet le PO.

n=>(8*n+1)**.5%1>0

L'essayer

f=
n=>(8*n+1)**.5%1>0
oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


Je pense que vous pourriez économiser un octet avec n=>(8*n+1)**.5%1>0(ce qui inverserait les sorties)
ETHproductions

@ETHproductions: OK, tant que vous le permettez. Est-ce que cela est normalement permis, cependant?
Shaggy

1
Il est qualifié de "deux sorties constantes et distinctes", alors oui. D'autres problèmes de décision peuvent toutefois nécessiter vérité / fausseté.
ETHproductions


3

Mathematica, 28 octets

!Accumulate@Range@#~FreeQ~#&

Je recommande de remplacer 7!par #. D'abord, c'est plus court. plus important encore, la solution actuelle n’est pas correcte, car elle impose artificiellement une limite à la taille de l’entrée sur laquelle il travaille.
Greg Martin

1
OP dit: "Vous pouvez supposer que l'entrée est un entier positif inférieur à 10 ^ 6" .Mais j'aime votre idée et je vais l'accepter, bien que la mienne donne le bon résultat pour chaque cas en utilisant une liste de 5040 éléments, mais votre pire cas a besoin d’une liste de 999999 éléments.Merci du pourboire!
J42161217

1
Oups, désolé, je n'ai pas vu le commentaire de l'OP! Oui, il y a des incitations « perverses » dans le code golf: que les économies de 1 octet est plus important dans une question de code golf que toute l'efficacité dans le monde :)
Greg Martin


3

Excel, 31 22 octets

9 octets sauvés grâce à Octopus

Sorties TRUEpour les nombres triangulaires. Sinon FALSE. Vérifie si 8*n+1est un carré parfait.

=MOD(SQRT(8*B1+1),1)=0

1
=MOD(SQRT(8*A1+1),1)=0sauve quelques octets
Octopus

2

Brachylog , 5 octets

≥ℕ⟦+?

Essayez-le en ligne!

Explication

≥ℕ⟦+?
≥ℕ     There is a number from 0 to {the input} inclusive
  ⟦    such that the range from 0 to that number
   +   has a sum
    ?  that equals the input


2

Python - 52 octets

Note: Je sais que les deux autres réponses en Python sont beaucoup plus courtes, mais c'est la manière de la vieille école, plus d'un algorithme à la main

n=input();i=s=0
while s<n:s=(i*i+i)/2;i+=1
print s>n

2

APL (Dyalog) , 6 octets

⊢∊+\∘

Essayez-le en ligne!

Explication

⊢∊+\∘
                       Creates a range from 1 to the right_argument
  +\                    Cumulative sum of this range; 1 1+2 1+2+3 .. 1+2+..+n. These are the triangular numbers
⊢∊                      Does the right argument belong to this list of integers in this cumulative sum

Sorties 0pour false et 1pour true.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.