Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Friday Golf: All 2-digit combinations

by PhilHibbs (Hermit)
on Sep 26, 2003 at 12:24 UTC ( #294388=perlmeditation: print w/ replies, xml ) Need Help??

Display a sequence of digits that contains every 2-digit pair once only. A sample program is provided.

To clarify, the output must contain all 100 combinations of two digits. It must contain '01' and '10', for example, but '010' would count for both of those pairs. '0110' would count as containing '01', '11', and '10'.

A two stroke bonus will be awarded for a sequence that is not just a (00..99).

Update: I fixed (well, bodged) my solution! Also, the two-stroke bonus is rather pointless, as other solutions are shorter anyway. My lack of imagination there, I'm afraid. I should have said "for code that does not itself contain any 2-digit pairs". Is it unfair to change the rules now? I don't think it changes the running order ATM.

for ('00'..'89'){ if (index($str,$_)<0) { if (index($str.substr($_,0,1),$_)<0) { if (index($str.substr($_,1,1),$_)<0) { $str.=$_; } else { $str.=substr($_,1,1); } } else { $str.=substr($_,0,1); } } } print $str.'90';
Output:
00102030405060708091121314151617181922324252627282933435363738394454647484955657585966768697787988990

I can get within a dozen characters of a hard-coded print statement (138 strokes):
for('00'..'89'){if($s!~/$_/){($a,$b)=/(.)(.)/;if(($s.$a)!~/$_/){if(($s.$b)!~/$_/){$s.=$_}else{$s.=$b}}else{$s.=$a}}}print$s.'90'
123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678
Can you do better?

Update: Fixed dumb mistake - missing '' around ..

Update: I believe that BrowserUK is in the lead so far, but I have just discovered that my solution was flawed, as it duplicated '09'.

Update: Dragonchild has also posted a correct solution, and a checker.

Update: Someone has taken the lead with an astonishing 28 characters! Who is that masked monk?

Here is some code that you can use to test your output:

$s = (<>); for('00'..'99'){print $_." missing\n" if $s!~/$_/} for('00'..'99'){print $_." duplicated\n" if index($s,$_) >= 0 and inde +x($s,$_,index($s,$_)+1) >= 0}

Comment on Friday Golf: All 2-digit combinations
Select or Download Code
Re: Friday Golf: All 2-digit combinations (wrong!)
by BrowserUk (Pope) on Sep 26, 2003 at 13:04 UTC

    Update: Both attempts in this node are bogus!!

    46?

    $n='00';$s!~/$n/and$s.=$n while$n++<99;print$s
    123456789 123456789 123456789 123456789 123456789

    45

    $n='00';$s!~$n and$s.=$n while$n++<99;print$s
    123456789 123456789 123456789 123456789 123456789


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

      44 if you die ;) why won't you die??? lol

      I do realize that the line number may not be wanted, but I just couldn't resist ;D

      MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
      I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
      ** The third rule of perl club is a statement of fact: pod is sexy.

      40.
      $n='00';/$n/ or$_.=$n while$n++<99;print
      123456789 123456789 123456789 123456789

      Update: your code still displays some bad entries. see below

      010203040506070809111213141516171819222324252627282933343536...etc.
      He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.

      Chady | http://chady.net/

      62? (Does anyone have a neat one liner for verifying this? trying to check the results is doing my eyes in:)

      $_=$n='00';/$n/ or$_.=$n and s/(.)\1\1/$1$1/while$n++<99;print
      123456789 123456789 123456789 123456789 123456789 123456789 123

      58!
      $_=$n='00';/$n/ or$_.=$n,s/(.)(?=\1\1)//while$n++<99;print
      123456789 123456789 123456789 123456789 123456789 123456789 123


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

        I believe that is the first correct solution! Congratulations, let the ++'s flow!

        See my original post for the checker.

        Congratz! Though, I think your algorithm works only because of a peculiarity in 00..99. If you extend it to 000..999, your algorithm doesn't scale, while mine does. :-)

        ------
        We are the carpenters and bricklayers of the Information Age.

        The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

        Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Friday Golf: All 2-digit combinations
by Chady (Priest) on Sep 26, 2003 at 13:14 UTC
    Please note that you have an error in your code, you've got 01 for example displayed more than once, (I got obviously late in posting)

    79.

    $_=join'',('00'..'99');1while(s/(..)(.*)\1/$1$2/);1while(s/(.)\1\1/$1$1/);print
    123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789

    75. (removed stupid parnes)

    $_=join'','00'..'99';1while s/(..)(.*)\1/$1$2/;1while s/(.)\1\1/$1$1/;print
    123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345

    He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.

    Chady | http://chady.net/
      You're missing 90
Re: Friday Golf: All 2-digit combinations
by LTjake (Prior) on Sep 26, 2003 at 13:31 UTC

    My half-assed try... 67

    for('00'..'99'){$a.=$_ unless $x{$_} or $x{reverse $_}++};print $a; #234567890#234567890#234567890#234567890#234567890#234567890#234567 # 1 2 3 4 5 6

    Note, it includes '00' which some people are missing...

    Update... 59? (similar to hardburn's solution)

    for('00'..'99'){$x{$_}++unless $x{reverse()}};print keys%x;

    Update 2 ...50?

    for$a(0..9){for(0..9){$x.="$a$_"if$_>=$a}}print$x;

    Update 3: after a clarification, i guess i've misunderstood the problem. I thought it needed all unique pairs, separately (ie. 00, 01, 02, 03...). My bad.

    Update 4: Here's one that actually passes the checker (60)

    $_=9;for$a(0..9){for$b($a..9){$_.="$a$b"}s/$a{3}/$a$a/}print

    Update... 57!

    $_=9;for$a(0..9){for$b($a..9){$_.="$a$b"}s/$a$a/$a/}print

    --
    "To err is human, but to really foul things up you need a computer." --Paul Ehrlich

      Take out two ';' and the whitespace after the unless and you're down three more strokes:

      for('00'..'99'){$x{$_}++unless$x{reverse()}}print keys%x

      56

      ----
      I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
      -- Schemer

      Note: All code is untested, unless otherwise stated

      56! {He he}

      $_=9;for$a(0..9){for$b($a..9){$_.=$a.$b}s/$a$a/$a/}print

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

        53.

        for$a(9,0..9){for$b($a..9){$_.=$a.$b}s/$a$a/$a/}print

        --
        "To err is human, but to really foul things up you need a computer." --Paul Ehrlich

Re: Friday Golf: All 2-digit combinations
by Rich36 (Chaplain) on Sep 26, 2003 at 13:46 UTC

    I'm certainly not going to win with a score of 132 (actually 130 minus the two strokes for not using(00..99)), but it's a different way to do it. I never was much good at golf anyway...

    $n{sprintf("%02d", $c++)}=1 until($c>99);for(keys %n){delete $n{$_}if( +$n{reverse($_)}&&reverse($_)!=$_)}print join('',sort keys %n)

    «Rich36»
Re: Friday Golf: All 2-digit combinations
by hardburn (Abbot) on Sep 26, 2003 at 13:55 UTC
    for('00'..'99'){$h{$_}++if(!($h{$_}||$h{reverse$_}))}print keys%h

    78 76 64

    Update: Slight bumming of the if statement to use statement-modifier form instead of a block. Saves 2 characters.

    Update 2: Realized that the exists were unnecessary. Saves 12 characters.

    Update 3: Old versions, added back after tye's response:

    for('00'..'99'){if(!(exists$h{$_}||exists$h{reverse$_})){$h{$_}++}prin +t keys%h
    for('00'..'99'){$h{$_}++if(!(exists$h{$_}||exists$h{reverse$_}))print +keys%h

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

      Generating ... 3738553956575859777879990001020304052206230724082509262744284529464748 +49666768698889111213141516173318341935361 Checking ... '00' appears 0 times

      Also, you can drop the braces for the if statement and go to 62.

      ------
      We are the carpenters and bricklayers of the Information Age.

      The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

        I'm not so sure about your checker:

        $ ./two_digit_combo.pl | perl -ne 'print join " ", sort unpack("A2" x +(length()/2), $_)' 00 01 02 03 04 05 06 07 08 09 11 12 13 14 15 16 17 18 19 22 23 24 25 2 +6 27 28 29 33 34 35 36 37 38 39 44 45 46 47 48 49 55 56 57 58 59 66 6 +7 68 69 77 78 79 88 89 99 $ cat two_digit_combo.pl #!/usr/local/bin/perl for('00'..'99'){$h{$_}++if(!($h{$_}||$h{reverse$_}))}print keys%h $

        Clearly, '00' is right at the beginning of the output.

        ----
        I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
        -- Schemer

        Note: All code is untested, unless otherwise stated

      Part of the fun of golf is watching the code get whittled away. Please don't destroy your previous versions when you update.

      I'm glad you left in the previous stroke counts, but sad that you destroyed the code that went along with those.

                      - tye
Re: Friday Golf: All 2-digit combinations
by dragonchild (Archbishop) on Sep 26, 2003 at 14:00 UTC
    The string posted doesn't meat the needs. Here's what I've got (84 chars):
    sub checker { my ($str) = @_; for ('00' .. '99') { my $n = 0; $n++ while $str =~ /$_/g; die "'$_' appears $n times\n" if $n != 1; } } sub generate { 0 1 2 3 4 5 6 + 7 8 #012345678901234567890123456789012345678901234567890123456789012345678 +90123456789012345 for$x(0..9){for$y(0..9){/$x$y/||(/^$y/and$_="$x$_")||(/$x$/and$_.=$y) +or$_.="$x$y"}}$_ } print "Generating ...\n"; my $test = generate(); print "$test\n"; print "Checking ...\n"; checker($test); print "Ok\n"; ---- Generating ... 9900102030405060708091121314151617181922324252627282933435363738394454 +6474849556575859667686977879889 Checking ... Ok

    I know it can be improved ...

    Update: 78 chars and counting ...

    #0 1 2 3 4 5 6 + 7 8 #012345678901234567890123456789012345678901234567890123456789012345678 +901234567890 for$x(0..9){for$y(0..9){/$x$y/||(/^$y/?$_=$x.$_:(/$x$/?$_.=$y:($_.=$x +.$y)))}}$_

    Update: 72 chars and counting ...

    #0 1 2 3 4 5 6 + 7 #012345678901234567890123456789012345678901234567890123456789012345678 +9012345 for$x(0..9){for$y(0..9){/$x$y/||($_=/^$y/?$x.$_:/$x$/?$_.$y:$_.$x.$y) +}}$_ for$x(0..9){for$y(0..9){$_=/$x$y/?$_:/^$y/?$x.$_:/$x$/?$_.$y:$_.$x.$y +}}$_

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      Yes, I believe that your solution is correct. BrowserUK beat you by one minute and a bunch of characters, but you included a checker, and spotted my mistake (which I won't pretend was deliberate). Well done.

      I'm not sure I agree with your character count, as the code doesn't print anything. Replacing $_ with print at the end adds three characters. However, you do qualify for a 2-stroke bonus under the revised rules for not using any 2-digit combinations in your code.

Re: Friday Golf: All 2-digit combinations
by hardburn (Abbot) on Sep 26, 2003 at 14:18 UTC

    Since most solutions have the numbers running together, I wrote up this little one-liner to help split the pairs apart:

    perl -ne 'print join " ", sort unpack("A2" x (length()/2), $_)'

    Just pipe the output of your Golf solution into it.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: Friday Golf: All 2-digit combinations
by BrowserUk (Pope) on Sep 26, 2003 at 14:53 UTC

    A one-liner for visually verifying the output:

    # assumes the output is in $s; print sort map{ substr $s, $_, 2 } 0..99;

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

Re: Friday Golf: All 2-digit combinations
by vanwie (Acolyte) on Sep 26, 2003 at 21:34 UTC
    49:
    $_=9;for($x=0;$x<=9;$x++){$_.=join $x,$x..9}print
    123456789 123456789 123456789 123456789 123456789

      Nice approach++ You can lose a few from that though, for 39.
      $_=9;for$a(0..9){$_.=join $a,$a..9}print
      123456789 123456789 123456789 123456789 123456789

      29.
      print+9,map{join$_,$_..9}0..9
      123456789 123456789 123456789 123456789 123456789


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

        One more stroke sh?aved:

        print+join$_,$_..9for+9,0..9

        I tried fiddling with the glob function without success. :-(

        /-\

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://294388]
Approved by reyjrar
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2014-07-30 10:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (230 votes), past polls