11
votes

Comment tester si une liste contient des entiers consécutifs à Mathematica?

Je veux tester si une liste contient des entiers consécutifs.

 consQ[a_] := Module[
  {ret = True}, 
  Do[If[i > 1 && a[[i]] != a[[i - 1]] + 1, ret = False; Break[]], {i, 
  1, Length[a]}]; ret]


0 commentaires

7 Réponses :


9
votes

Vous pouvez utiliser

consQ[a : {Integer___}] := MatchQ[Union@Differences[a], {1} | {-1} | {}]
consQ[_] = False


4 commentaires

Puisque vous testez que l'ensemble de la différence est exactement {1} , il suffit de vérifier que la liste contient un entier, au lieu de les vérifier.


Ou sans les contraintes d'intégrité: CONQ [A_]: = Union @ Différences [A] === {1}. Frais. Il est difficile de choisir entre votre solution et celle par champion. - (Je n'étais pas au courant de Mathematica avait la fonction des différences.)


S'il vous plaît jeter un oeil à la modification: et plus loin en question. Comment modifieriez-vous votre consQ?


Merci pour la modification. @Szabolcs - J'aime votre réponse pour sa lisibilité, sa compacité et son style fonctionnel, même si techniquement, cela pourrait ne pas être le plus rapide. - La variété des solutions montrent le pouvoir de Mathematica.



11
votes

La solution de SzableLics est probablement ce que je ferais, mais voici une alternative: xxx

Notez que ces approches diffèrent dans la manière dont ils gèrent la liste vide. >


7 commentaires

Et aussi la liste de taille 1. J'aime mieux le vôtre.


Rapide, fonctionnel et compact. :-) Mais cryptique (pour moi), où l'Union @ Différences est proche de l'auto-documentant. - Il est difficile de décider lequel est le meilleur! - Les deux laissent ma "solution" loin derrière la performance-sage.


Mais facilement décomposé. Définir a = {1,2,3,4,5} et aller de là.


S'il vous plaît jeter un oeil à la modification: et plus loin en question. Comment modifieriez-vous votre consQ?


@nilo, vous pouvez suivre le plomb de Belisarius 'LEPLOW et UTILISER SIGN : MOST [A] + SIGN [A [[2]] - A [[1]]] === Reste [A ]


@Monsieur. Voulez-vous dire que vous voulez dire signe [- # [[1]] + # [[2]]]] & @ {A [[[1]], A [[- 1]]} ?


@belisarius signe [{- 1,1} .a [[{1, -1}]]]]



8
votes

J'aime les solutions par les deux autres, mais je serais préoccupé par de très longues listes. Considérez les données

{0.000076, False}


4 commentaires

Je ne suis pas un expert chronométrant mais ne tient pas la fonction de choisir lors de la comparaison des vitesses d'algorithme SEC? - Je demande parce que je reçois des résultats différents lors de l'utilisation de timing au lieu d'absolutimer. - Je suis intéressé quelle solution utilise l'algorithme le plus rapide.


@niloderoock, j'ai ajouté des données de synchronisation, en utilisant timing à ma réponse.


@belisarius, absolument. Donne-moi quelques heures.


@belisarius, alors je, je vois mon Wiki Réponse .



5
votes

pli peut être utilisé dans une expression assez concise qui fonctionne très rapidement: xxx

correspondance de modèle peut être utilisé pour fournir une expression très claire de l'intention à Le coût des performances sensiblement plus lentes: xxx

edit

consisque , comme écrit, fonctionne en mathématica v8.0.4 mais pas dans les versions antérieures de V8 ou V7. Pour corriger ce problème, il y a quelques alternatives. Le premier consiste à nommer explicitement le point de retour : xxx

la seconde, comme suggéré par @ M.Wizard, est de remplacer retour avec lancer / attrape : xxx


5 commentaires

C'est ce que j'ai pensé quand j'ai lu la question, mais vous ne voulez pas utiliser lancer plutôt que retour ?


@ M.Wizard lancer fonctionnerait également, mais il nécessiterait une prise correspondante . retour est donc plus concis car il quitte la construction de la société la plus proche (dans ce cas, la définition de consisque ).


@ M.Wizard AHA! Je vois le problème maintenant. retour semble être cassé dans la version 7 et 8.0.1. Il est à nouveau fixé dans la version 8.0.4 (ou cassé, en fonction de votre point de vue :).


Combien de constructions retourne-t-il avec 8.0.4? Oh, et bien sûr, +1.


@ M.Wizard Il semble y avoir beaucoup de traditions d'entourer retour - et peu de faits. La documentation officielle est clairsemée. Par exemple, le formulaire à deux arguments est presque non documenté . J'ai été surpris plus d'une fois par le comportement documenté: si [le deuxième argument] est omis, la fonction ou la boucle concernée est déterminée à l'aide de l'heuristique intégrée . Je suppose que j'aurais dû savoir mieux que de m'avoir informé et j'avais la fortune (MIS) d'essayer mon code dans le nouveau 8.0.4 brillant.



8
votes

Je pense que ce qui suit est également rapide, et la comparaison des listes inversées ne prend pas plus de plus:

a = Range[2 10^7];
Timing@consQSzab@a
Timing@consQBret@a
Timing@consQBeli@a
(*
{6.5,True}
{0.703,True}
{0.203,True}
*)


2 commentaires

Notre- hangar.co.uk/blog/wp-content/uploads/2010/01/...


@Monsieur. Regardez vos manières! Retour Kicking, pondre des œufs géants et manger des feuilles d'eucalyptus n'est autorisée que sur www.stackoverflow.co.au



5
votes

Je suis maintenant convaincu que Belisarius essaie d'obtenir ma chèvre en écrivant du code intentionnellement compliqué. :-p

J'écrirais: f = la plage [##, signe [# 2 - #]] & @@ # [[{1, -1}]] == # &

En outre, je crois que Wrach avait probablement l'intention d'écrire quelque chose comme: xxx


2 commentaires

-14 pour ingénierie inverse mon code protégé par le droit d'auteur et obscurcie


Il y a un vin pour votre Problème de chèvre .



5
votes

Puisque le timing semble être plutôt important. J'ai déplacé les comparaisons entre les différentes méthodes à ce sujet, la réponse de la communauté, la réponse.

Les données utilisées sont simplement des listes de nombres entiers consécutifs, avec un seul point non consécutif, et ils sont générés via < Pré> xxx

où la première forme de dat [n] est équivalente à dat [n, 1] . Le code de timing est simple: xxx

Il génère 100 entiers aléatoires entre 1 et chacun des {10, 25, 50, 100, 250, 500, 1000} < / Code> et DAT utilise ensuite chacun de ces nombres aléatoires comme point non consécutif dans une liste de 10 000 éléments longs. Chaque implémentation consQ est ensuite appliquée à chaque liste produite par dat et les résultats sont moyennés. La fonction de traçage est simplement xxx

Données de synchronisation pour diverses fonctions

J'ai chronométré les fonctions suivantes consqszabolcs1 , consqszabolcs2 , consQBett , CONSQRCOLLYER , , consqwrffolf , consqwrfol2 , consqwrfol3 , consQwrmatch et Version de MRWizard de consQBelisarius . < / p>

en ordre croissant de la gauche la plupart du temps: consQBelisarius , consQWizard , CONSQRCOLLYER , CONSKBRETT , CONSQSZABOLCS1 , CONSQWRMATCH , CONSQSZABOLCS2 , CONSQWLIOLD2 , consqwrfol3 et consQwrffold .

EDIT : RERAN TOUTES LES FONCTIONS AVEC TimeaVG (le second) au lieu de < Code> Timing dans consQTIMing . J'ai toujours fait plus de 100 points, cependant. Pour la plupart, il y avait une modification, à l'exception des deux les plus bas où il y a une variation de la course à courir. Donc, prenez ces deux lignes avec un grain de sel car ils sont pratiquement identiques.

Entrez la description de l'image ici


8 commentaires

@belisarius, l'a poussé à autoriser des points non consécutifs aléatoires à 5000 et 10000 et à une image mise à jour.


@Belisarius, celui juste au-dessus de la vôtre, qui plonge au-dessous de la vôtre entre 50 et 1000.


Oui, mais quelle fonction est-ce? Il y a deux fonctions dans la réponse de M.


@Belisarius, je pensais que je l'ai fait clairement dans le texte, apparemment pas. C'est sa version de votre fonction, f . Je n'ai pas pris la peine avec l'autre, car Wrond a appliqué ce correctif à consQwrfol3 . Donc, j'étais assez surpris que la synchronisation ait une différence dans le timing.


Désolé je n'ai pas compris. Merci beaucoup!


@RCollyer Souhaitez-vous tester Belisarius 'et mes fonctions à nouveau, en utilisant Timeeavg ou similaire? Je suis curieux de savoir si, sur votre système, le vacillement vu sur le mien est réel ou un artefact.


@ M.Wizard, Reran toutes les fonctions avec Timeavg , et il existe une variation pour le vôtre et le Belisarius 'de fonctionner à exécuter.


Merci. Il semble être une simple variation, plutôt que d'être plus rapide que l'autre, ce que j'attendais.