ID generator with no matching contiguous pairs

16

4

Given 2 inputs (m=minimum starting id, n=number of ids), generate a sequential list of ids, starting at >=m, made up of the digits 0-9 where no 2 contiguous numbers are the same, e.g. 1232 is ok, 1233 is not (contains 2 '3's next to each other).

Example

for m=985, n=6, below shows what ids would be generated/skipped

...
985 - ok, 1st
986 - ok, 2nd
987 - ok, 3rd
# skip 0988 (contains '88')
989 - ok, 4th
# Skip 099x (contains '99')
# Skip 100x (contains '00')
1010 - ok, 5th
# Skip 1011 (contains '11')
1012 - ok, 6th
...

Output

Each ID should be printed on a new line, as for the above sequence:

985
986
987
989
1010
1012

Rules

Standard code-golf rules, lowest byte count wins

beirtipol

Posted 2018-02-28T15:45:37.697

Reputation: 679

14Welcome to PPCG! Each ID should be printed on a new line I highly discourage explicitly restricting the output to a particular format. – Erik the Outgolfer – 2018-02-28T15:51:04.243

1Test case: an input where m has consecutive identical digits. It shouldn't cause anybody to trip up but it'll be nice to have for people to consider. Say, m=988, n=3. – Giuseppe – 2018-02-28T15:55:45.637

3Is it okay to return a list of IDs (i.e. a 1-D array of integers), instead of printing to stdout? – JungHwan Min – 2018-02-28T15:56:21.407

Wait a minute... don't immediately answer challenges that has something that should/may/can be fixed (in this case, the strict output format) – user202729 – 2018-02-28T15:59:29.207

As, if the rules are kept they're bad, and if they're changed existing answers are invalidated (suboptimal). – user202729 – 2018-02-28T16:00:36.897

4@user202729 The answers won't be invalidated in this case. – Erik the Outgolfer – 2018-02-28T16:07:31.027

@EriktheOutgolfer But suboptimal. Doing more than what the challenge requires is invalid. – user202729 – 2018-02-28T16:21:47.440

2@user202729 That doesn't make answers invalid... If anything, the answers will either get fixed or they're just following the old rules. – totallyhuman – 2018-02-28T16:27:22.843

1@EriktheOutgolfer - First time on here, why is specifying the output format discouraged? Many of the code golf questions I've looked at are specifically about outputting information in a certain format (e.g. output as a square / christmas tree etc.) – beirtipol – 2018-02-28T17:11:33.753

2

@beirtipol Outputting in a very specific format is discouraged for challenges whose main point is not the output. [tag:ascii-art] challenges are all about outputting things, that's why they are allowed to do it. But requiring us to join the results by newlines adds nothing to the challenge, but rather adds unnecessary bytes to the submissions. See Things to avoid when writing challenges.

– Mr. Xcoder – 2018-02-28T17:16:38.343

Aha, understood. Will note it for next time. Looking at some of the answers below, I think that changing the question to remove this would be unfair? – beirtipol – 2018-02-28T17:19:57.603

3For the ones written in golfing languages changing the rule to allow more output formats wouldn't affect them. For the rest you can just leave a comment saying the output format isn't restricted anymore. – Brad Gilbert b2gills – 2018-02-28T17:42:46.993

Can n be 0 ? – Ton Hospel – 2018-02-28T20:06:54.427

@beirtipol So is the output restricted or not? Can I print the numbers as strings enclosed in quotes ("989"...)? – Asone Tuhid – 2018-02-28T20:20:44.187

I'll leave output restricted as is. Don't think I should change the rules now after submission – beirtipol – 2018-03-01T11:46:35.840

@TonHospel - yes, n could be 0 – beirtipol – 2018-03-01T11:46:59.547

Answers

3

Jelly, 6 bytes

DIẠµ#Y

Try it online!

How it works?

DIẠµ#Y – Full program. Argument: two integers, X and Y.

   µ#  – Return the first Y integers higher than or equal to X that satisfy:
 I     – The increments ...
D      – ... Of their base-10 digits ...
  Ạ    – ... Are all non-0. 
     Y – Join the result by newlines.

Mr. Xcoder

Posted 2018-02-28T15:45:37.697

Reputation: 39 774

8

Brachylog, 11 10 bytes

{≤ṫẹ~ḅẉ}ᶠ⁾

Input is a list of two numbers. Try it online!

Explanation

The built-in takes a list or string, like "1000220", and splits it into blocks of equal adjacent elements, like ["1","000","22","0"]. In this program, I apply the ~ operator to it, so it works in reverse: it takes a list of strings, checks that each string consists of repetitions of a single character and neighboring strings have different characters, and concatenates the list. The predicate enumerates numbers starting from the first input in increasing order, and I check a condition on them, printing those that satisfy it and stopping when I've found enough.

{≤ṫẹ~ḅẉ}ᶠ⁾  Input is a pair, say [M=988,N=3].
{      }ᶠ⁾  Apply this predicate to M and compute the first N results.
 ≤          Take a number that is greater than or equal to M (first up is 988).
  ṫ         Convert it to string: "988"
   ẹ        Split it into substrings of length 1: ["9","8","8"]
     ~ḅ     Apply ḅ in reverse: fails, try next number.
       ẉ    If ḅ succeeds, print the resulting string and a newline.
            This counts as a result of the predicate.

Zgarb

Posted 2018-02-28T15:45:37.697

Reputation: 39 083

6

05AB1E, 9 bytes

µÐÔQi=¼}>

Try it online!

Exlpanation

µ           # loop until counter equals n
 Ð          # triplicate current value (initially m)
  Ô         # connected uniqueified on the copy at the top of the stack
   Q        # compare to unmodified for equality
    i  }    # if true
     =      # print current value while leaving it on the stack
      ¼     # increment the counter
        >   # increment current value

Emigna

Posted 2018-02-28T15:45:37.697

Reputation: 50 798

4

Java 8, 83 bytes

(m,n)->{for(;n>0;m++)if(!(m+"").matches(".*(.)\\1.*")){System.out.println(m);n--;}}

Explanation:

Try it online.

(m,n)->{                      // Method with two integer parameters and no return-type
  for(;n>0;                   //  Loop as long as `n` is larger than 0
      m++)                    //    After every iteration: increase `m` by 1
    if(!(m+"").matches(".*(.)\\1.*")){
                              //   If there are no repeated adjacent digits:
      System.out.println(m);  //    Print `m`
      n--;}}                  //    And decrease `n` by 1

Kevin Cruijssen

Posted 2018-02-28T15:45:37.697

Reputation: 67 575

Very nice. Out of curiosity, where would be the appropriate forum for this question where the challenge wasn't "bytes" but "efficiency"? – beirtipol – 2018-02-28T17:22:03.690

1@beirtipol By most efficient you mean fastest execution time? In that case probably also here on PPCG, with the tags code-challenge and fastest-code. Although posting the exact same challenge now and changing code-golf to fastest-code will probably still be closed as a dupe.. – Kevin Cruijssen – 2018-02-28T20:40:04.690

3

R, 111 92 71 bytes

function(m,n)while(F<n){if(!grepl("(.)\\1",m)){cat(m,'
');F=F+1}
m=m+1}

Try it online!

Uses grepl to search for repeated digits.

Giuseppe

Posted 2018-02-28T15:45:37.697

Reputation: 21 077

You don't join the result by newlines, and the OP didn't respond if this is allowed yet (though I hope It'll be fine) – Mr. Xcoder – 2018-02-28T16:25:44.560

@Mr.Xcoder ah, right, I noticed that and then copied and pasted the wrong version :( – Giuseppe – 2018-02-28T16:29:19.337

3

PowerShell, 59 bytes

param($m,$n)for(;$n){if("$m"-notmatch"(.)\1"){$m;$n--}$m++}

Try it online!

Basically similar to the other answers. Loops so long as we have numbers left to print (for(;$n)), tests whether we have a regex match against a double-digit and if not it puts that on the pipeline and decreases $n. Then we increment $m and loop again. The elements are picked up from the pipeline and the implicit Write-Output gives us a newline-separated output for free.

AdmBorkBork

Posted 2018-02-28T15:45:37.697

Reputation: 41 581

2

Jelly, 9 bytes

DŒgZLỊµ#Y

Try it online!

If not for the output restriction, Y can be removed.

Erik the Outgolfer

Posted 2018-02-28T15:45:37.697

Reputation: 38 134

2

C, 73 bytes

k;f(s,n){for(;n--;printf("%d\n",s++))for(k=s;k;)k=k%10-k/10%10?k/10:++s;}

Try it online!

Steadybox

Posted 2018-02-28T15:45:37.697

Reputation: 15 798

2

Perl 6, 56 bytes

{.put for grep({none .comb Zeq.comb.skip},$^a..*)[^$^b]}

Try it

Expanded:

{  # bare block lambda with placeholder params $a $b

  .put for

  grep(

    {
      none          # create a none junction (True if all are False)

        .comb       # the input split into digits
        Zeq         # Zip using &infix:«eq» operator
        .comb.skip  # the input split into digits starting at second one
    },

    $^a .. *        # a Range starting at the first argument

  )[ ^ $^b ]        # take the first $b values
}

Brad Gilbert b2gills

Posted 2018-02-28T15:45:37.697

Reputation: 12 713

2

Perl 5.10.0 + -n, 40 39 bytes

for(;$i;$_++){!/(.)\1/&&$i--&&say}$i=$_

Try it online!

-1 byte thanks to Xcali

Input on two lines, first n, then m. Make sure that there is NO newline after m:

(echo '6'; echo -n '985') | perl -nE 'for(;$i;$_++){!/(.)\1/&&$i--&&say}$i=$_'

wastl

Posted 2018-02-28T15:45:37.697

Reputation: 3 089

1You can eliminate the 'm' to save a byte. – Xcali – 2018-02-28T17:59:39.143

@Xcali Thanks, don't know what I was thinking ... – wastl – 2018-02-28T18:08:40.240

2

Perl 5, -ln 33 bytes

Enter 2 lines on STDIN, first starting id then count

#!/usr/bin/perl -ln
$n-=!/(.)\1/&&say,$_++while$n.=<>

Try it online!

Ton Hospel

Posted 2018-02-28T15:45:37.697

Reputation: 14 114

I did not know that $n.=<> worked like that, especially with the -=... – Dom Hastings – 2018-03-01T11:49:02.037

@DomHastings Unfortunately I'll have to roll it back since $n can be 0 so doing them both together is wrong – Ton Hospel – 2018-03-01T12:48:05.907

2

Retina, 34 bytes

.0A`
"$+"{\/(.)\1/{`.+
*
)C`
.+
*

Try it online! Takes n and m as input on separate lines. Explanation:

.0A`

Turn off automatic output and delete n from the work buffer.

"$+"{

Repeat n times.

\

Print the value of m at the end of the following looped group.

/(.)\1/{`

Loop while there are contiguous digits.

.+
*

Convert to unary.

)C`

Count the number of empty strings, which is one more than the number of characters, thus adding 1 and converting back to decimal. This ends the inner loop.

.+
*

Having printed m, add 1 again in the same way. (The last line doesn't need a C` because it's the default stage type for the last line.) The outer loop is implicitly ended.

Note that converting to unary and back to decimal is a little slow; for 39 bytes, a version that doesn't do any conversion:

.0A`
"$+"{\/(.)\1/+`.+
$.(*__
.+
$.(*__

Try it online! Explanation: $.( calculates the length of the rest of the substitution, conveniently without actually expanding it; since the length of *_ is implicitly the matched value and the length of _ is of course 1 this just increments the value.

Neil

Posted 2018-02-28T15:45:37.697

Reputation: 95 035

1

Stax, 9 8 bytesCP437

ç@F6╕↔┤ú

Try it online!

Happen to coincide with @Mr.Xcoder's algorithm in his Jelly answer.

-1 byte per comment by @recursive.

Explanation

Uses the unpacked format to explain.

{$:-|A}gn
{     }gn    Generator, generate given number of values, using block as a filter
                 And implicit output, one element on a line.
             In Stax, only 0 and [] is falsy.

 $           Convert the number to string
  :-         Difference between contiguous digit
    |A       All of them are truthy (may use `:*` as well)

Weijun Zhou

Posted 2018-02-28T15:45:37.697

Reputation: 3 396

https://staxlang.xyz/#c=%C3%A7%40F6%E2%95%95%E2%86%94%E2%94%A4%C3%BA&i=985+6%0A99+3&a=1&m=2 gives 8 bytes. Implicit eval works on multiple values as long as they're on the first line of standard input. – recursive – 2018-02-28T17:23:54.300

@recursive Thank you, that is something I didn't notice although it is documented. – Weijun Zhou – 2018-02-28T17:29:01.223

1

Haskell, 94 93 91 bytes

-1 byte thanks to Laikoni
-2 bytes thanks to Zgarb

import Data.List
a!0=[]
a!b|all(null.tail)$group$show a=show a++'\n':(a+1)!(b-1)|c<-a+1=c!b

Try it online!

First Haskell golf.

ovs

Posted 2018-02-28T15:45:37.697

Reputation: 21 408

1Welcome to Haskell golfing! group(show a) can be group$show a. – Laikoni – 2018-02-28T16:45:16.667

2(<2).length can be null.tail – Zgarb – 2018-03-01T08:15:14.420

1

Python 2, 80 73 bytes

-7 bytes thanks to Mr. Xcoder

m,n=input()
while n:
 if~-sum(i*2in`m`for i in`99**9`):print m;n-=1
 m+=1

Try it online!

Rod

Posted 2018-02-28T15:45:37.697

Reputation: 17 588

1

Haskell, 70 bytes

-19 bytes thanks to nimi.

s#n=unlines$map show$take n$filter(and.(zipWith(/=)=<<tail).show)[s..]

Try it online!

17 bytes dedicated to separating by newlines.

totallyhuman

Posted 2018-02-28T15:45:37.697

Reputation: 15 378

153 bytes – nimi – 2018-02-28T16:22:08.987

You don't join the result by newlines, and the OP didn't respond if this is allowed yet (though I hope It'll be fine) – Mr. Xcoder – 2018-02-28T16:24:46.073

@Mr.Xcoder Agh, fixing... – totallyhuman – 2018-02-28T16:26:04.737

1

You can use mapM and print. Try it online!

– nimi – 2018-02-28T16:33:15.100

0

Pyth, 12 bytes

j.f.A.+jZTEQ

Try it here

Mr. Xcoder

Posted 2018-02-28T15:45:37.697

Reputation: 39 774

0

JavaScript (ES6), 50 bytes

Takes input in currying syntax (m)(n).

m=>g=n=>n?/(.)\1/.test(m++)?g(n):~-m+`
`+g(n-1):''

Try it online!

Arnauld

Posted 2018-02-28T15:45:37.697

Reputation: 111 334

0

C# (.NET Core), 91 bytes

m=>n=>{for(;n-->0;System.Console.WriteLine(m++))for(int k=m;k>0;k=k%10!=k/10%10?k/10:++m);}

Port of @Steadybox' C answer.

Try it online.

Kevin Cruijssen

Posted 2018-02-28T15:45:37.697

Reputation: 67 575

0

Perl 5 (-nl), 42 bytes

$l=<>;do{!/(.)\1/&&$l--&&say}while++$_&&$l

Try it online!

Xcali

Posted 2018-02-28T15:45:37.697

Reputation: 7 671

0

AWK, 90 bytes

{for(j=$1;k<$2;j++){for(a=b=d;++b<=(n=split(j,A,""))&&a!=c=A[b];a=c);if(n<b&&++k)print j}}

Try it online!

This is a lot uglier than I thought it would be. I discovered that AWK only has back-substitution in its gensub function which would make it not very efficient to use for this application.

So this is a very straightforward approach of incrementing an ID counter, splitting the counter at each character, looping through the characters to see if any character is the same as the previous character. If no repeated characters are found, print the ID counter and increment the number of IDs printed.

I will try to refrain from making a statement along the lines of "AWK should have the ability to do more robust regular expressions", but it will be difficult.

Robert Benson

Posted 2018-02-28T15:45:37.697

Reputation: 1 339

0

Bash + GNU utilities, 35

seq $1 inf|egrep -v '(.)\1'|sed $2q

Try it online.

Digital Trauma

Posted 2018-02-28T15:45:37.697

Reputation: 64 644

0

Ruby, 47 bytes

->s,n{/(.)\1/!~s&&p(s)&&n-=1;s.next!;n>0&&redo}

Try it online!

If you don't like the quote marks, it's 50 bytes

->s,n{puts s if/(.)\1/!~s&&n-=1;s.next!;n>0&&redo}

Try it online!

Asone Tuhid

Posted 2018-02-28T15:45:37.697

Reputation: 1 944

0

Pip, 22 bytes

--aLb{W`(.)\1`N++a0Pa}

Try it online!

Explanation

--aLb{W`(.)\1`N++a0Pa}
                        a,b are command-line arguments
--a                     Decrement a
   Lb{               }  Loop b times:
       `(.)\1`           Regex matching a character followed by itself
      W       N++a       While that regex matches in incremented a:
                  0       No-op
                   Pa    When the while loop exits, a is a valid ID; print it

DLosc

Posted 2018-02-28T15:45:37.697

Reputation: 21 213