Crazy 8s Code Golf

34

3

Create a program that prints all whole numbers inclusively between an interval (a, b), and replaces multiples of 8 in the sequence with random (uniformly distributed, independent of other characters), non-numeric, non-whitespace, printable ASCII characters.

Assume 0 < a < b in all cases.

If the number has more than 1 digit, make sure the amount of characters in the replacement matches!

Examples:

(1, 16) -> 1 2 3 4 5 6 7 $ 9 10 11 12 13 14 15 n@

(115, 123) -> 115, 116, 117, 118, 119, :F<, 121, 122, 123

(1, 3) -> 1 2 3

Non-Examples:

(1, 16) -> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

(115, 123) -> 115 116 117 118 119 $ 121 122 123

This is code golf, so the shortest code in bytes wins!

Current Winner:

Pyke (21 bytes) by muddyfish

Most Popular:

Python 2 (119 bytes) by Dennis

GracefulLemming

Posted 2016-12-23T23:56:34.193

Reputation: 863

11Congrats on making a challenge that combines all the super long things to implement in my golfing language – Blue – 2016-12-24T00:16:03.277

1@muddyfish i mean it is a challenge ;) – GracefulLemming – 2016-12-24T00:16:47.477

I'm not sure if I am missing something, but should the random characters be unique or not? For example if the input was 16, 16 then could the output be aa? If this is not the case, what about if the number has more than 85 digits (assuming I counted correctly)? – FryAmTheEggman – 2016-12-24T04:09:58.093

@FryAmTheEggman each character should be unique mostly but if "a" and "a" are randomly selected consecutively that is ok, but it shouldnt happen in all cases because the probability is so low – GracefulLemming – 2016-12-24T04:14:10.773

@FryAmTheEggman and the case 16, 16 in the other examples either returns 0 or 2 random characters but dont worry about that case as a will always strictly be less than b – GracefulLemming – 2016-12-24T04:15:06.600

What do we do with non-ASCII encodings?

– Adám – 2016-12-25T10:07:53.733

Can we choose such random chars (guaranteed to be random): http://xkcd.com/221/ ?

– RudolfJelin – 2016-12-25T13:15:48.270

Can 8 be randomly selected? – steenbergh – 2017-01-06T17:50:59.993

@steenbergh no, random characters must be non-nuneric – GracefulLemming – 2017-01-06T17:59:17.163

@Caleb Hmm, missed that bit of the specs. That's expensive... – steenbergh – 2017-01-06T18:23:38.873

Answers

4

Pyke, 22 21 bytes

h1:Fi8%!I`lV~Kl7T>Hs0

Try it here!

Takes input in the form: higher, lower

h1:                   -  range(lower, higher+1, 1)
   F                  - for i in ^:
    i8%               -    i % 8 
       !              -   not ^
        I             -  if ^:
         `l           -    len(str(i))
           V          -   repeat V ^ times
            ~K        -        printable_ascii
              l7      -       ^.strip()
                T>    -      ^[10:]
                  H   -     random.choice(^)
                   s0 -    sum(^)

Blue

Posted 2016-12-23T23:56:34.193

Reputation: 26 661

Lists are all good! – GracefulLemming – 2016-12-24T16:53:28.740

This is interesting, the first case ive seen where 8n, 8n causes an error – GracefulLemming – 2016-12-24T16:57:17.273

my bad I misread the output – GracefulLemming – 2016-12-24T16:59:52.677

11

Python 2, 126 bytes

Try it online!

import random,string
def f(a,b):
 while b/a:print[a,eval('random.choice(string.printable[10:-6])+'*len(`a`)+"''")][a%8<1];a+=1

Many thanks to Flp.Tkc and EasterlyIrk for all of their help!

heather

Posted 2016-12-23T23:56:34.193

Reputation: 219

2

You can use b/a instead of a<=b and you don't need the ; at the end. Also import random,string saves a few bytes. https://tio.run/nexus/python2#TcvdCoIwGAbg813FEGJbW9anJGF1JSL4qVsO5pQldflL9KTD9@eJdpynsNCAvp9G9V6C9S/Sa0MNR9WKktDvYJ2m7RnLeR2XCpX@oONsJ2k3TLbTfJfpdsHW6Qou5amohWRHpz1vsBEyYSwRdYWH2wPqO8onRMNBQSHI5sia4Kogy/8KlYv4Aw

– Dennis – 2016-12-24T16:16:30.313

@Dennis, thank you, that took off 7 bytes! – heather – 2016-12-24T16:59:58.047

10

Python 2, 119 bytes

import random,string
def f(a,b):print`[random.choice(string.printable[10:95])for _ in`a`]`[2+a%8*b::5]or a;a<b<f(a+1,b)

Try it online!

Dennis

Posted 2016-12-23T23:56:34.193

Reputation: 196 637

4To quote Flp.Tkc: "One does not simply outgolf Dennis" – GracefulLemming – 2016-12-24T19:07:50.677

6

zsh, 100 98 bytes

for i in {$1..$2};{((i%8))&&<<<$i||<<<`yes 'shuf -e {!..~}|grep "[^0-9]"|head -c1'|head -$#i|zsh`}

The two input arguments are passed as command line arguments, and the numbers are output on separate lines.

for i in {$1..$2};{   # loop through the range
((i%8))&&             # if the number is not divisible by 8 (i % 8 != 0),
<<<$i||               # output it
<<<`                  # otherwise, output the following:
yes '                 # using `yes' as a golfy loop
shuf -e {\!..\~}      # shuffle the range of printable ASCII (minus space)
|grep "[^0-9]"        # get rid of numbers
|head -c1'            # take the first character
|head -$#i            # obtain a string with that code repeated len(i) times... 
|zsh                  # ... and eval it
`}

Doorknob

Posted 2016-12-23T23:56:34.193

Reputation: 68 138

May I ask why you are outputting the numbers that are divisible by 8? – GracefulLemming – 2016-12-24T00:56:29.467

1@Caleb Whoops, that was a typo. It was meant to read "not divisible by 8." – Doorknob – 2016-12-24T01:03:02.623

5

Mathematica, 96 bytes

Range@##/.a_?(8∣#&):>Join[33~(c=CharacterRange)~47,58~c~127]~RandomChoice~⌊Log10@a+1⌋<>""&

Explanation

For inputs m and n:

Range@##

Generate {m, m + 1, m + 2, ... , n}

/.a_?(8∣#&):>

For all numbers that are divisible by 8 (call that a), apply this replacement rule:

Join[33~(c=CharacterRange)~47,58~c~127]

Get a list of all printable ASCII characters, except digits.

... ~RandomChoice~⌊Log10@a+1⌋

Pseudo-randomly choose Floor[Log10[a] + 1] characters from the list, allowing duplicates.

<>""

Join the characters.

JungHwan Min

Posted 2016-12-23T23:56:34.193

Reputation: 13 290

another approach for 96 bytes using FromCharacterCode (r=Range)@##/.a_?(8∣#&):>FromCharacterCode[Join[33~r~47,58~r~127]~RandomChoice~⌊Log10@a+1⌋]<>""& – buttercrab – 2019-02-06T14:13:41.980

5

R, 73 bytes

i=scan();x=i[1]:i[2];x[!x%%8]=sample(sapply(c(32:46,58:126),intToUtf8));x

Reads input from stdin and replaces replaces numbers divisible by 8 with a uniformly chosen sample of ascii characters in the range 32...47, 58...126. To draw the random sample we need a vector of characters, unfortunately intToUtf8() returns one string rather than a vector so we also have to vectorize it over the range using sapply.

Billywob

Posted 2016-12-23T23:56:34.193

Reputation: 3 363

5

Python 2, 126 bytes

(one does not simply outgolf Dennis)

Seeing as I did a lot of work on heather's answer, I thought I'd post my own solutions too.

import random,string
def f(a,b):
 while b/a:print[a,eval('random.choice(string.printable[10:-6])+'*len(`a`)+"''")][a%8<1];a+=1

This is a function which takes two arguments and prints directly to STDOUT.

127 bytes

import random,string
lambda a,b:[[x,eval('random.choice(string.printable[10:-6])+'*len(`x`)+`''`)][x%8<1]for x in range(a,b+1)]

This is an unnamed anonymous function - to use, assign to a variable (such as f), and then call with f(a, b). This returns the output as a list.

FlipTack

Posted 2016-12-23T23:56:34.193

Reputation: 13 242

This is incorrect. The randomly selected characters may not contain digits. – Dennis – 2016-12-24T16:20:36.913

@Dennis alright, back to my splicing idea :P Thanks for the heads up – FlipTack – 2016-12-24T16:23:44.023

Python 2 seems to be popular contender, i love it! – GracefulLemming – 2016-12-24T16:50:31.137

4

Pip, 28 bytes

Fia,b+1Pi%8?i{RC@>PA@`\D`}Mi

Takes the numbers as command-line arguments and prints a newline-separated list of results. Try it online!

Explanation:

                              a,b are cmdline args; PA is string of all printable ASCII
Fia,b+1                       For i in range(a, b+1):
       P                       Print this:
        i%8?i                  If i%8 is truthy (nonzero), i; otherwise:
             {           }Mi   Map this function to the digits of i:
                @>PA           All but the first character of PA (removes space)
                    @`\D`      Find all regex matches of \D (nondigits)
              RC               Random choice from that list of characters
                               The map operation returns a list, which is concatenated
                               before printing

DLosc

Posted 2016-12-23T23:56:34.193

Reputation: 21 213

4

JavaScript (ES6), 114 bytes

f=(x,y)=>(x+"").replace(/./g,d=>x%8?d:String.fromCharCode((q=Math.random()*84)+(q>15?43:33)))+(x<y?[,f(x+1,y)]:"")

O.textContent = f(1,200)
<pre id=O>

Those darn built-ins with 23-byte names....

ETHproductions

Posted 2016-12-23T23:56:34.193

Reputation: 47 880

1The replacement chars should be non-numerical – LarsW – 2016-12-24T22:08:18.527

@LarsW Somehow missed that, thanks – ETHproductions – 2016-12-25T01:50:46.937

3

MATL, 26 bytes

&:"@8\?@}6Y24Y2X-Xz@VnT&Zr

Try it online!

Explanation

&:        % Input a and b (implicit). Push range [a a+1 ... b]
"         % For each k in that range
  @       %   Push k
  8\      %   Modulo 8
  ?       %   If non-zero
    @     %     Push k
  }       %   Else
    6Y2   %     Push string of all printable ASCII chars
    4Y2   %     Push string '0123456789'
    X-    %     Set difference
    Xz    %     Remove space. Gives string of possible random chars
    @Vn   %     Push number of digits of k
    T&Zr  %     Random sample with replacement of that many chars from the string
          % End if, end for each, display (implicit)

Luis Mendo

Posted 2016-12-23T23:56:34.193

Reputation: 87 464

Wow, cool! Nice answer. +1 – heather – 2016-12-24T00:54:01.807

@heather Thanks! I have a feeling it could be made shorter... – Luis Mendo – 2016-12-24T00:55:42.343

3

Pyth, 24 bytes

jm?%d8dsmO-r\~\ jkUT`d}F

Try it online!

Explanation:

jm?%d8dsmO-r\~\ jkUT`d}FQ  # Auto-fill variables
                      }FQ  # Splat inclusive range on the input
 m?%d8d                    # Map over each number, if it isn't divisible by 8 return it
       smO          `d     # for each other number, select a character at random for
                             each of it's digits and then flatten into one string
           r\~\            # Printable ASCII excluding space
          -     jkUT       # Setwise difference with numeric values (remove numbers)
j                          # Join with newlines

FryAmTheEggman

Posted 2016-12-23T23:56:34.193

Reputation: 16 206

3

Bash + apg, 64, 76 bytes

EDITS:

  • Fixed the "8 8" issue, exclude numeric characters from a set of random chars, +12 bytes

Golfed

seq $1 $2|sed "$[(7&(8-$1%8))+1]~8s/.*/a=&;apg -a1 -n1 -Mcsl -m\${#a} -x0/e"

Test

>./crazy8 8 8
$

>./crazy8 115 123
115
116
117
118
119
As_
121
122
123

>./crazy8 1 16
1
2
3
4
5
6
7
"
9
10
11
12
13
14
15
x!

zeppelin

Posted 2016-12-23T23:56:34.193

Reputation: 7 884

Could you give is a brief walk through? Also im curious to see what crazy8 8 8 would yield – GracefulLemming – 2016-12-24T16:06:44.753

@Caleb, actually it will just output a as is, for 8 8, looks like I've over-golfed it a bit, working on a fix now. It also does not filter out digits from the random string character set (I've missed that too). – zeppelin – 2016-12-24T20:08:31.733

2

Perl 6, 60 bytes

{map {$_%8??$_!!S:g/./{grep(/\D/,"!".."~").pick}/},$^a..$^b}

Explanation:

  • { map { }, $^a .. $^b }: A lambda that takes two arguments, generates the list of integers in that range, and returns it with the following transformation applied to each element:
  • $_ % 8 ?? $_ !!: If the element is not divisible by 8, pass it on unchanged. Otherwise...
  • S:g/./{ }/: ...replace each character of its string representation with the value generated by this expression:
  • grep(/\D/, "!" .. "~").pick: Generate the range of characters between ! and ~ (in Unicode order), filter out digits, and randomly pick one of the remaining characters.

smls

Posted 2016-12-23T23:56:34.193

Reputation: 4 352

1

PHP, 163 bytes

$n=range(48,57);$c=array_diff(range(32,126),$n);
foreach(range($a,$b) as $v){if($v%8!=0){echo $v;}
else{for($i=0;$i<strlen($v);$i++){echo chr($c[array_rand($c)]);}}}

Explanation:

  • $n = range(48,57) These are the ASCII codes for numbers, which are in the middle of special characters (32-47) and other characters (58-126).
  • $c = array_diff(range(32,126), $n) Using the $n array, exclude numeric characters and build an array of acceptable ASCII characters.
  • foreach(range($a,$b) as $v) Loop over the range of values from $a to $b (inclusive), as $v inside the loop.
  • if($v % 8 != 0) { echo $v; } Test for $v being evenly divisible by 8 using the mod operator %.
  • else { for($i = 0; $i < strlen($v); $i++) { ... }} If not evenly divisible by 8, loop enough times for the number of digits in the number and print the characters (in the next step).
  • echo chr($c[array_rand($c)]) Print a single character from the acceptable array of ASCII values in $c. array_rand returns an index in the array, so we have to get the actual value at that index using $c[random_key].

I could probably make this smaller by creating $c differently, and the loop to print the ASCII characters feels clunky so I'll continue to ponder how to shorten that.

Jake Bathman

Posted 2016-12-23T23:56:34.193

Reputation: 111

1Thanks Jake! Glad to hear from you! Take a look at my new challenge Random Pixel Poking if you have time too! – GracefulLemming – 2016-12-24T19:23:44.953

1

Scala, 198 bytes

An improved functional version with immutable state (03-04-2018)

  def S(a: Int, b: Int)={
    val c=(33 to 47)++(58 to 126)
    val r = (a to b).toStream.map {case x if x%8==0=>c(Random.nextInt(c.length)).toChar.toString
      case x => String.valueOf(x)}
    r}

Try it online!

A functional style solution in Scala (350 bytes) for the fun of it.

def r(a:Int, b:Int)={
    var l=(33 to 47).toList:::(58 to 126).toList
    l=Random.shuffle(l)
    var x=ListBuffer[String]()
    var k=0
    (a to b).toList.foreach{e=>{
         if(k==l.length){k=0
         l=Random.shuffle(l)}
         if (e.toInt%8==0){x+=l(k).toChar.toString
           k+=1}
         else{x+=e.toString
             k+=1}}}
    x}

Suggestions for improvements are welcomed.

firephil

Posted 2016-12-23T23:56:34.193

Reputation: 211

1Here on code golf se we only allow answers which have been at least attempted to be golfed. This means 1 character variable names and removal of spaces android adding a byte count to your answer – Blue – 2016-12-25T09:05:54.747

@muddyfish ok i golfed my code, how is android adding the byte count ? – firephil – 2016-12-25T15:22:37.577

It seems fine to me right now – Blue – 2016-12-25T15:23:55.583

1

postgresql9.6 251 chars

very long code but postgresql also does it.

do language plpgsql $$ begin for n in a..bloop raise info'%',case when 0=n%8then(select array_to_string(array(select*from(select chr(generate_series(33,126)))t where chr!~'\d'order by random()limit floor(log(n))+1),''))else n::text end;end loop;end;$$

formatted sql is here:

do language plpgsql $$
begin
for n in a..b loop
    raise info '%',
    case when 0 = n % 8 then (
        select array_to_string(array(select * from (
            select chr(generate_series(33, 126))
        ) t where chr !~ '\d' order by random() limit floor(log(n)) + 1), '')
    ) else n::text
    end;
end loop;
end;
$$

andryk

Posted 2016-12-23T23:56:34.193

Reputation: 81

1

Perl, 66 bytes

map{$_%8||s%.%do{$_=chr rand 126}until/[!-\/:-~]/;$_%ge;say}<>..<>

Run with -E flag:

perl -E 'map{$_%8||s%.%do{$_=chr rand 126}until/[!-\/:-~]/;$_%ge;say}<>..<>' <<< "8
16"

This is pretty straight forward:
-<>..<> creates a list of the numbers between the 2 inputs number. And then map iterates over it:
-$_%8||... : the ... are executed only if $_ is a multiple of 8.
-s%.%xxx%ge : replace every character with xxx.
- do{$_=chr rand 126}until/[!-\/:-~]/ pick a random character (from codes 0 to 126) until we get one that satisfies /[!-\/:-~]/, ie. one that is printable and is not a digit.
- say: print it.

Dada

Posted 2016-12-23T23:56:34.193

Reputation: 8 279

1

Java 10, 149 147 bytes (lambda function)

b->a->{var r="";for(;a<=b;r+=" ",a++)for(var c:(a+"").split("")){char t=0;for(;t<33|t>126|t>47&t<59;t*=Math.random())t=127;r+=a%8<1?t:c;}return r;}

Try it online.

Java 10, 227 225 bytes (full program)

interface M{static void main(String[]A){var r="";for(var a=new Long(A[0]);a<=new Long(A[1]);r+=" ",a++)for(var c:(a+"").split("")){char t=0;for(;t<33|t>126|t>47&t<59;t*=Math.random())t=127;r+=a%8<1?t:c;}System.out.print(r);}}

Try it online.

Explanation:

b->a->{          // Method with two integer parameters and String return-type
  var r="";      //  Result-String, starting empty
  for(;a<=b      //  Loop as long as `a` is smaller than or equal to `b`
      ;          //    After every iteration:
       r+=" ",   //     Append a space to the result-String
       a++)      //     And increase `a` by 1
    for(var c:(a+"").split("")){
                 //   Inner loop over the characters of the current number
      char t=0;  //    Random-char, starting at 0
      for(;t<33|t>126|t>47&t<59;
                 //    Loop until `t` is a non-digit printable ASCII char
          t*=Math.random())t=127;
                 //     Set `t` to a random character with a unicode in the range [0,127)
      r+=a%8<1?  //   If the current `a` is divisible by 8:
          t      //    Append the random character
         :       //   Else:
          c;}    //    Append the digit instead
  return r;}     //  Return the result

Kevin Cruijssen

Posted 2016-12-23T23:56:34.193

Reputation: 67 575

range [0,127] does not conform to spec: "non-numeric, non-whitespace, printable ASCII" – O.O.Balance – 2018-04-04T14:59:38.733

@O.O.Balance Maybe my comment isn't very well explained, but that's where the t<33|(t>47&t<59)|t>126; is for above it. It basically generated a random number in the range [0,127), then checks if it's valid (so in the range [33..47,59..126], all printable non-digit ASCII characters). If it is: good, append it. If not: generate a random number in the range [0,127) again and validate it again until we've found a valid character. – Kevin Cruijssen – 2018-04-04T15:27:26.957

No, I think your comment is fine. My bad :) – O.O.Balance – 2018-04-04T15:46:02.390

1

C, 157 115 bytes

f(a,b){b-a&&f(a,b-1);if(b%8)printf("%d",b);else for(;b;b/=10){while(isdigit(a=rand()%94+33));putchar(a);}puts("");}

Try it online here. Thanks to jxh for golfing 42 bytes.

Ungolfed version:

f(a, b) { // recursive function, parameters are implicitly int
    b-a && f(a, b-1); // recurse until a = b
    if(b % 8)            // if the number is a multiple of 8
        printf("%d", b); // simply print it
    else for(; b; b /= 10) { // while b > 0, lop off the last digit
        while(isdigit(a = rand() % 94 + 33)); // generate random characters in ASCII range [33, 127] until one is non-numeric
        putchar(a); // print the character
    }
    puts(""); // print a newline
}

O.O.Balance

Posted 2016-12-23T23:56:34.193

Reputation: 1 499

This conversation can be continued in chat.

– James – 2018-04-13T19:05:36.650

1

C (gcc), 129 119 bytes

s(a,r){a&&s(!isdigit(r=rand()%94+33)?putchar(r),a/10:a,0);}f(a,b){b>a&&f(a,b-1);b%8?printf("%d",b):s(b,0);printf(" ");}

Try it online!

129 &rightarrow; 119 Use the %94+33 trick from O.O.Balance

Ungolfed:

s(a,r){
    a&&                                  // Loop recursively on a!=0
    s(!isdigit(r=rand()%94+33)           // Test random selection
      ?putchar(r),a/10                   // Print and reduce a
      :a                                 // Retry random selection
      ,0);                               // Second arg, recurse
}
f(a,b){
    b>a&&                                // Loop recursively on b>a
    f(a,b-1);                            // Reduce b, recurse
    b%8?printf("%d",b)                   // Print non 8's
       :s(b,0);                          // Call s() for 8's
    printf(" ");                         // Space separator
}

jxh

Posted 2016-12-23T23:56:34.193

Reputation: 331

You can save 3 bytes if you change to a newline separator (puts instead of printf). – O.O.Balance – 2018-04-13T09:12:18.657

It's more fun to play with your solution :-) – jxh – 2018-04-13T18:51:13.127

1

APL (Dyalog Extended), 32 bytes

{(?84¨⍕⍵)⊇⎕D~⍨'!'…'~'}¨@{0=8|⍵}…

Try it online!

Huge thanks to Adám and dzaima for their help. First time using Dyalog Extended!

Explanation:

{(?84¨⍕⍵)⊇⎕D~⍨'!'…'~'}¨@{0=8|⍵}…  ⍝ Dyadic 2-train

                               …  ⍝ Tacit range: list of numbers from left arg 
                                  ⍝ to right arg inclusive
{(?84¨⍕⍵)⊇⎕D~⍨'!'…'~'}¨@{0=8|⍵}   ⍝ Monadic function applied to above          
                        {     }   ⍝ Function definition
                           8|⍵    ⍝ 8 modulo every item in our range
                         0=       ⍝ Transform list into a boolean vector, with
                                  ⍝ 1 where item was equal to zero, 0 otherwise
                      ¨@          ⍝ Applies left function to each item selected
                                  ⍝ by above
{                    }            ⍝ Function definition
              '!'…'~'             ⍝ Range of all printable ASCII chars
          ⎕D~⍨                    ⍝ Remove numeric characters from above
 (    ⍕⍵)                         ⍝ Convert function argument to string
                                  ⍝ (e.g., 123 -> "123")
   84¨                            ⍝ For each character, replace with number 84
                                  ⍝ (number of non-numeric printable ASCII chars)
  ?                               ⍝ Generate random number from 1-84 for each
                                  ⍝ 84 in list
         ⊇                        ⍝ Index the ASCII char list with above random
                                  ⍝ numbers

voidhawk

Posted 2016-12-23T23:56:34.193

Reputation: 1 796

0

Python 2, 180 Bytes

from random import*
def f(a,b):
 for i in range(a,b+1):
  if i%8<1:
   k,i=str(i),''
   for _ in k:i+=choice([chr(j)for j in range(33,48)]+[chr(j)for j in range(57,126)])
  print i

EDIT:

Thanks @Flp.Tkc for realising I hadn't read the task properly.

Thanks @Caleb for pointing out I could use a few to reduce the byte count.

Thanks @Dennis for pointing out about the fact that numbers can't be included.

EDIT 2:

The current version could probably be simplified more than it is.

sonrad10

Posted 2016-12-23T23:56:34.193

Reputation: 535

0

PowerShell, 82 89 bytes

$a,$b=$args;$a..$b|%{($_,(-join[char[]](33..47+58..127|random -c "$_".Length)))[!($_%8)]}

Try it online!

briantist

Posted 2016-12-23T23:56:34.193

Reputation: 3 110

158..127 does not include the printable ASCII symbols in the lower range 33 (!) to 47 (/). – zeppelin – 2016-12-25T18:33:48.783

@zeppelin true, I didn't think that was a requirement, but re-reading it, I suppose it must be if it's to be a uniform distribution. Updated! – briantist – 2016-12-25T18:47:12.370

0

QBIC, 79 bytes

::[a,b|~c%8=0|[_l!c$||_R33,116|~e>47 and e<58|e=e+z]Z=Z+chr$(e)]\Z=Z+!c$]Z=Z+@ 

Skipping the numbers is a costly affair, here's a version that might also randomly select 0-9 for 20 bytes less:

::[a,b|~c%8=0|[len(!c$)|Z=Z+chr$(_r33,126|)]\Z=Z+!c$]Z=Z+@ 

Sample output for 1, 89

1 2 3 4 5 6 7 U 9 10 11 12 13 14 15 M9 17 18 19 20 21 22 23 ^L 25 26 27 28 29 30 
31 <U 33 34 35 36 37 38 39 gH 41 42 43 44 45 46 47 aJ 49 50 51 52 53 54 55 1b 57 58 59 60 
61 62 63 ,C 65 66 67 68 69 70 71 ]; 73 74 75 76 77 78 79 [B 81 82 83 84 85 86 87 Ix 89 

Explanation:

::        Get inputs 'a' and 'b' from the command line
[a,b|     FOR(c=a; c<=b; c++)
~c%8=0|   IF c is cleanly divisible by 8 THEN
 _l!c$|   Take the length (_l) of the string representation (! ... $) of c 
[      |  FOR (d = 1; d<= length(c); d++)
_R33,116| Set e to a random value in the range 33 - 116 (all the printable ascii's - 10)
~e>47     IF e falls between 47
and e<58| and 58 (ASCII code for 0-9) THEN 
e=e+z     e = e + 10 (z == 10 in QBIC)
]         END IF
Z=Z+      Add to Z$
chr$(e)]  ASCII character e
\         ELSE if c is not cleanly divisible by 8
Z=Z+!c$   Add to Z the string representation of c
]         NEXT
Z=Z+@     Add a space to Z$ (@ is an implicitly delimited string literal with 1 significant space)

( Z$ is implicitly printed at end of program )

steenbergh

Posted 2016-12-23T23:56:34.193

Reputation: 7 772

0

PHP, 130 bytes

function($a,$b){for(;$a<=$b;$a++)echo$a%8?$a:(function($l){while($l--)echo chr(($x=rand(44,128))-($x>58?:11));})(strlen($a))," ";}

Try it online!

Ungolfed:

function c8( $a, $b ) { 
    for( ; $a<=$b; $a++ ) {                // loop between a -> b
        echo $a % 8 ? $a :                 // every 8, call anon func instead of value
            (function($l) {
                while( $l-- ) {            // repeat length of value
                    $x = rand( 44, 128 );  // range size is printable chars [33,47][58,127]
                    $x-= $x > 58 ?: 11;    // Subtract one from x. If x was less than or 
                                           // equal to 58, subtract a further ten from it
                                           // so that it now falls within the 33-47 range
                    echo chr( $x );        // echo ASCII value
                }
            })( strlen( $a ) )," ";
    }
}

640KB

Posted 2016-12-23T23:56:34.193

Reputation: 7 149

Yes, my mistake. Regarding $x-= $x > 58 ?: 11; // subtract 11, if x is less than 58 -- could you elaborate? – Jonathan Frech – 2019-02-05T22:49:10.783

@JonathanFrech in other words we want a number that's between 33-47 or 58-127. So we pick a number that's 58 minus the size of the lower range. If the number is below 58 it's just translated down to the lower range by subtracting the difference. Because of course we can't display numbers (ASCII char 48-57) – 640KB – 2019-02-05T22:53:10.013

The ternary is just a shortcut to doing it. Basically $x > 58 evaluates to 1, and so we either subtract that or 11 from $x. In the case where it's higher, it's offset by the ASCII values in the rand() statement being one higher. You can see that this generates a uniformly random (as uniform as PHP's rand() is capable of) distribution: https://tio.run/##K8go@G9jXwAkVRIVbBUSi4oSKzU0rbm40vKLNFQqbQ2sFVQqFWwUDA2AAMTW1lbQ5OJUSYyOBSrXUKmwLUrMS9EwMdExNLLQ1NQFitiZWthbGRqCDCnOLyrRUACaDOIUFGXmlcQXaUAsiU/OLwVyyxJzSlOLIWqAqv7/BwA

– 640KB – 2019-02-05T23:02:21.093

I think I know roughly what the Elvis operator does, I just think your comment is misleading. – Jonathan Frech – 2019-02-05T23:13:08.613

I would think it works like Subtract one from x. If x was less than or equal to 58, subtract a further ten from it., no? – Jonathan Frech – 2019-02-05T23:39:00.277

@JonathanFrech, that's it. I'll update the comment to make it more clear. Thanks for your suggestions! – 640KB – 2019-02-06T13:42:28.843

0

05AB1E, 17 bytes

ŸεD8ÖižQžhK¦.rsg£

Takes the input as highest\nlowest, and outputs a list.

Try it online or verify all test cases.

Explanation:

Ÿ                  # Create a list in the range [low (implicit) input, high (implicit) input]
 ε                 # Map each value to:
  D                #  Duplicate the value
   8Öi             #  If it's divisible by 8:
      žQ           #   Push all printable ASCII characters (" " through "~")
        žhK        #   Remove all digits
           ¦       #   Remove the first character (the space)
            .r     #   Randomly shuffle the remaining characters
              s    #   Swap to take the map value again
               g   #   Get its length
                £  #   And leave that many characters from the string
                   # (and implicitly output the resulting list after we're done mapping)

Kevin Cruijssen

Posted 2016-12-23T23:56:34.193

Reputation: 67 575

0

Japt, 20 bytes

;òV ®%8?Z:EÅk9ò)öZìl

Try it

;òV ®%8?Z:EÅk9ò)öZìl     :Implicit input of integers U & V
 òV                      :Range [U,V]
    ®                    :Map each Z
     %8                  :  Modulo 8
       ?Z:               :  If truthy, return Z, else
;         E              :  Printable ASCII
           Å             :  Slice off first character
            k            :  Remove
             9ò          :    Range [0,9]
               )         :  End remove
                 Zì      :  Digit array of Z
                   l     :  Length
               ö         :  Get that many random characters from the string

Shaggy

Posted 2016-12-23T23:56:34.193

Reputation: 24 623

0

Forth (gforth), 128 bytes

include random.fs
: f 1+ swap do i 8 mod if i . else i 0 <# #s #> 0 do 83 random 33 + dup 47 > 10 * - emit loop ."  "then loop ;

Try it online!

Explanation

Loop from start to end, print number if not multiple of 8, otherwise get the number of digits in the number and print that many random characters followed by a space

Code Explanation

include random.fs          \ include/import the random module
: f                        \ start new word definition
  1+ swap                  \ add 1 to end number, because forth loops are [start, end), and swap order
  do                       \ start counted loop form start to end
    i 8 mod                \ get the remainder of dividing i (loop index) by 8
    if                     \ if true (not 0, therefore not multiple of 8)
      i .                  \ print the index
    else                   \ otherwise
      i 0                  \ convert index to double-length number
      <# #s #>             \ use formatted numeric output to convert number to a string
      0 do                 \ loop from 0 to (string-length - 1)
        84 random          \ get random number between 0 and 83
        33 +               \ add 33
        dup 47 >           \ check if result is larger than 47
        10 * -             \ if it is add 10 to result (results in number in range: 33-47,58-126)
        emit               \ output ascii char corresponding with number
      loop                 \ end inner loop
    ."  "then            \ output a space and then close the if/else
  loop                   \ end the outer loop
;                        \ end the word definition

UnGolfed

I don't usually ungolf my solutions, but this one is long/complicated enough that I think it's needed

include random.fs

\ get the length (in digits) of a number
: num-length 0 <# #s #> nip ;

\ check if a number is a multiple of another
: is-multiple mod 0= ;               

\ get a random printable non-digit ascii char           
: random-char 84 random 33 + dup 47 > 10 * - ;  

\ get a "random" string of printable ascii chars the same length as a number
: rand-str num-length 0 do random-char emit loop space ;

\ print numbers from a to b, replacing multiple of 8 with a random ascii string of the same length
: crazy-eights 1+ swap do i 8 is-multiple if i rand-str else i . then loop ;

reffu

Posted 2016-12-23T23:56:34.193

Reputation: 1 361

0

Kotlin, 136 bytes

{r:IntRange->var s=""
for(i in r){for(c in "$i"){var n=java.util.Random().nextInt(83)
if(n>14)n+=10
s+=if(i%8>0)c
else '!'+n}
s+=" "}
s}

Try it online!

JohnWells

Posted 2016-12-23T23:56:34.193

Reputation: 611