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.

qwr
la source
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));
}
edc65
la source
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;
}
ouvriroufermer
la source
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.

Paul R
la source
3

Javascript

14 jetons

function max (a, b, c)
{
    var ab = (a >= b) * a + (a < b) * b;
    return (ab >= c) * ab + (ab < c) * c;
}
Fabricio
la source
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é :)

Mardoxx
la source
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;
}
Émeute
la source
Échec pour les grands nombres (> 2 ^ 30), voir le commentaire codegolf.stackexchange.com/questions/32476/#comment68870_32477
edc65
Ça
Riot
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)
ɐɔıʇǝɥʇuʎs
la source
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

}

jihed gasmi
la source
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];
}
EvilFonti
la source
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

Refroidisseur de mathématiques
la source
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)
}
djhurio
la source
0

Brainfuck (pas en compétition)

>,[-<+>>>+<<]>,[-<+>>>+<<]>[>[-<->>]<<]<[-]>[-]>[-]<<<[->>>>+<<<<]>>>>[-<+>>>+<<]>,[-<+>>>+<<]>[>[-<->>]<<]<<
rpax
la source
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

l4m2
la source
-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.

Alex
la source
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 :)

jcdude
la source
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