Trouver le maximum de 3 numéros sans branchement


17

Cette fois, votre objectif est de trouver le maximum de 3 entiers (de - (2 ^ 31) à 2 ^ 31 - 1 en complément binaire 2) sans utiliser de branchement ou de boucles.

Vous n'autorisé à utiliser

  • L' inégalité / l' égalité ( ==, >, >=, <, <=, !=) Ceux - ci comptent comme 2 jetons.

  • Arithmétique ( +, -, *, /)

  • Opérateurs logiques ( !pas, &&et, || ou)

  • Opérateurs de bits ( ~non, &et, |ou, ^xor, <<, >>, >>>gauche arithmétiques et logiques et décalages à droite)

  • Constantes. 0 jetons

  • Affectation variable. 0 jetons

Entrez 3 variables comme a, bet c. Sortez le nombre maximum.

Les règles standard de golf à code atomique s'appliquent. Si vous avez des questions, veuillez les laisser dans les commentaires. Un jeton est l'un des ci-dessus avec les règles spéciales.


Qu'en est-il de la définition d'une fonction supplémentaire? Si cela est autorisé, combien de jetons cela compte-t-il?
afuous

@voidpigeon Vous n'êtes autorisé à avoir qu'une seule fonction, celle qui prend les 3 entrées et sorties.
qwr

1
À première vue, je me suis dit " nous l'avons déjà fait " , mais je pense que les comparateurs coûtant 2 modifient un peu le jeu.
primo

@primo J'ai spécifiquement demandé 3 entrées car cela permet en fait des améliorations intéressantes
qwr

2
Pouvons-nous utiliser des fonctions intégrées?
Utilisateur enregistré le

Réponses:


7

Javascript 10 jetons

Modifier en utilisant <et * au lieu de bidouiller les bits - comme indiqué dans les commentaires, les opérations sur les bits peuvent échouer pour une entrée proche de la limite de plage (plus de 30 bits)

function Max(x,y,z)
{
  var d=y-x;
  x=y-d*(d<0);
  d=x-z;
  return x-d*(d<0);
}

Jetons C 8

Indépendant du langage en fait, n'importe quel langage de type C fera l'affaire. Pour être pointilleux, en C standard, il n'est pas portable car le décalage à droite peut ne pas étendre le signe (mais dans les implémentations courantes, il le fait).

En C (et C ++, C # et Java je pense), nous pouvons facilement gérer les problèmes de débordement en utilisant des valeurs temporaires plus grandes:

int Max(int x, int y, int z)
{
    long long X = x;
    long long Y = y;
    long long Z = z;
    long long D = Y-X;
    X=Y-((D>>63)&D);
    D=X-Z;
    return (int) (X-((D>>63)&D));
}

1
Je suis difficile, mais en utilisant C, intvotre code ne fonctionne pas pour x = 2147483647, y = -2, z = 0. Votre choix si vous voulez le changer
qwr

10

Javascript

6 jetons

function maxOf3(a, b, c) {
    (b>a) && (a=b);
    (c>a) && (a=c);
    return a;
}

6
+1 Je considère l'évaluation des raccourcis comme un type de branchement, mais ce n'est pas interdit dans les règles
edc65

11
Je considérerais cela comme une ramification, haha
juste le

2
@ edc65 C'est le cas. Permettant &&et ||probablement un oubli, qui devrait être souligné plutôt qu'exploité.
primo

@primo C'était une question intéressante. Je crois que certaines architectures du CISC ont des instructions qui incluent des instructions conditionnelles, donc je ne sais pas comment elles seraient comptées.
qwr

2
Je suppose que ce devrait être 4 jetons, c'est-à-dire 2 &&, <et >. Le =est utilisé comme une affectation et compte pour 0
Clyde Lobo

6

C: 10 jetons

int max(int a, int b, int c)
{
    a += (b > a) * (b - a);
    a += (c > a) * (c - a);
    return a;
}

Inspiré par la réponse de @ openorclose, mais converti en C et rendu sans branche en utilisant la multiplication plutôt que les opérateurs booléens en court-circuit.


3

Javascript

14 jetons

function max (a, b, c)
{
    var ab = (a >= b) * a + (a < b) * b;
    return (ab >= c) * ab + (ab < c) * c;
}

1
Vous n'êtes pas autorisé à créer de nouvelles fonctions
qwr

:( 14 jetons ensuite
Fabricio

2

Plusieurs langues (Python) (10 jetons)

def max3(x,y,z):
    m = x ^ ((x ^ y) & -(x < y))
    return m ^ ((m ^ z) & -(m < z))

print max3(-1,-2,-3) # -1
print max3(-1,2,10) # 10

https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax

Oh, quelqu'un l'a déjà posté :)


Vous n'êtes pas autorisé à créer de nouvelles fonctions
qwr

Ah d'accord! N'a pas lu les commentaires :)
Mardoxx

@qwr Je ne comprends pas, vous avez dit: You are only allowed to have one function, the one that takes the 3 inputs and outputs.c'est exactement ce que cette réponse a. Les 2 tirages ne sont que des cas de test
Cruncher

1
@Cruncher J'ai modifié la réponse que j'ai faite max2(max2(x,y),z)initialement :)
Mardoxx

@Mardoxx ah. Eh bien +1
Cruncher

1

Jetons C ++ 11:15

Utiliser uniquement des opérateurs arithmétiques et au niveau du bit (car les opérateurs d'égalité et de logique booléenne le rendent trop facile) ...

#include <iostream>

auto max(int32_t a, int32_t b, int32_t c)->int32_t {
  return c - ((c - (a - ((a - b) & (a - b) >> 31))) & (c - (a - ((a - b) & (a - b) >> 31))) >> 31);
}

auto main()->int {
  // test harness
  std::cout << max(9, 38, 7) << std::endl;
  return EXIT_SUCCESS;
}

Échec pour les grands nombres (> 2 ^ 30), voir le commentaire codegolf.stackexchange.com/questions/32476/#comment68870_32477
edc65


Avez-vous réellement lu le commentaire? Je pense que 2 milliards sont supérieurs à 0 [ ideone.com/vlcnq9 ]
edc65

Ah, je vois; oui, il y a un problème avec ces chiffres dans votre autre commentaire, quand un 0 est impliqué. Mais pas pour 2 ^ 30 comme vous l'avez dit. ideone.com/LicmXa
Riot

Ce n'est pas le 0 impliqué. Le problème est le grand nombre et le débordement, essayez max (2000000000, -200000000, 1111111111).
edc65

0

J (pas en compétition)

Je me demandais juste à quoi ressemblerait une solution dans J. Cela utilise un ,et un #bien, donc ce ne sera pas en compétition.

((a<b),(b<c),(c<a))#b,c,a

Ce serait en concurrence, mais c'est beaucoup trop long, avec 9 jetons:

(b*a<:b)+(c*b<c)+(a*c<a)

0

nous avons les hypothèses suivantes:

  • max (a; b) = (a + b + | ab |) / 2

  • max (a; b; c) = max (max (a; b); c)

  • abs (a) = (a + (a >> 31)) ^ (a >> 31)

on peut utiliser le pseudo-code:

fonction max (a, b, c)

{

out1 = ((a + b) + (((ab) + ((ab) >> 31)) ^ ((ab) >> 31))) div 2

out2 = ((out1 + c) + (((out1-c) + ((out1-c) >> 31)) ^ ((out1-c) >> 31))) div 2

retour2

}


Veuillez écrire le code réel et fournir le nombre de jetons dans votre réponse.
ProgramFOX

0

C # (2e essai)

Je l'ai compris ... Pas de fonctions intégrées ...

Mais est-il autorisé à utiliser d'autres types de données intégrés ou tout simplement un entier? Si autorisé, je proposerais:

int foo2(int a, int b, int c)
{
   var x = new SortedList<int,int>();

   x[a] = 1;
   x[b] = 1;
   x[c] = 1;

   return x.Keys[2];
}

0

jetons javascript 8

bien que similaire à la réponse de @ openorclose, j'utilise en fait les opérateurs logiques pour l'affectation elle-même.

function max( a, b, c ) {
    x=( a > b && a) || b;
    return ( x > c && x ) || c;
}

violon


0

R (10 jetons)

function max(a, b, c) {
  max <- a
  max <- max + (b - max) * (b > max)
  max <- max + (c - max) * (c > max)
  return(max)
}

0

Brainfuck (pas en compétition)

>,[-<+>>>+<<]>,[-<+>>>+<<]>[>[-<->>]<<]<[-]>[-]>[-]<<<[->>>>+<<<<]>>>>[-<+>>>+<<]>,[-<+>>>+<<]>[>[-<->>]<<]<<

0

TIS-100, 8 opérations

MOV ACC UP #A
SUB UP     #B
SUB 999
ADD 999
ADD UP     #B
SUB UP     #C
SUB 999
ADD 999
ADD UP     #C
MOV ACC DOWN

Le fournisseur (UP) ne fait que des MOV, donc non indiqué dans le code Peut-être ne fonctionne pas lorsqu'il est trop près du bord 999


-1

VBA (6 jetons)

 Function max3(a As Integer, b As Integer, c As Integer)
 i = IIf(a >= b And a >= c, a, IIf(b >= c, b, c))
 max3 = i
 End Function  

Je ne sais pas si ce n'est pas une ramification.


Il est ramifié, uniquement en ligne. Plus précisément, l'opérateur ternaire omniprésent (ce qui est essentiellement le cas) n'est pas l'une des opérations autorisées.
tomsmeding

Merci @tomsmeding, puis-je demander quel est l'opérateur ternaire omniprésent (est-ce IIF () dans mon code?)
Alex

oui désolé, avec omniprésent, je voulais dire qu'il est présent dans à peu près toutes les langues, et l'opérateur ternaire est le vôtre IIf, Inline-If. Dans la plupart des langues, c'est par exemple le cas a>=b ? a : b. Il se ramifie en effet.
tomsmeding

-1

JavaScript: 4 jetons (** basé sur une interprétation large de "affectation"!)

Évidemment, mon score de 4 est extrêmement généreux / indulgent!

Pour arriver à ce score, j'ai supposé que «l'affectation» (valant 0 jeton dans la question) comprend des éléments tels que l'affectation additive, l'affectation soustractive, l'affectation multiplicative et l'affectation XOR-ing ( ^=)

function f(a, b, c) {
  d = a;
  d -= b;
  d = d >= 0;

  a *= d;  //a = a if (a>=b), else 0
  d ^= true; //invert d
  b *= d;  //b = b if (b<a), else 0

  a += b;  //a is now max(a,b)

  d = a;
  d -= c;
  d = d >= 0;

  a *= d;  //a = a if (a>=c), else 0
  d ^= true; //invert d
  c *= d;  //c = c if (c<a), else 0
  a += c;  //a is now max(max(a,b),c)

  return a;
}

Si ces affectations comptent réellement, le score est de 14 :)


Parce que d -= bc'est en fait la même chose que d = d - b, je dirais que vous utilisez l'arithmétique et que vous devez compter cela comme un jeton.
ProgramFOX

Oui, je me rends compte que - j'essayais (en plaisantant) de profiter du sens de «affectation». Je pense que je l'ai rendu assez évident!
jcdude du
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.