Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Your program has to print out a number of spaces, followed by a dot and a newline. The number of spaces is the x position of your dot defined with 0 < x < 30

Every new line is a turn. Your program runs for 30 turns. Your program starts with a random x position and every turn shifts this position randomly by 1 to the left or right, while staying inside the defined area. Every turn your dot has to change its position by 1.

Your score is the number of characters. You get 10 bonus points, if every printed line consists of exactly 30 characters (and newline). You get 50 bonus points, if, while random, your program tends to stay in the middle of the defined area.

Edit: The 50 bonus points are intended to pull your dot to the middle. For example, this apply's if your dot is at x=20 and has a chance of 66% to go left and 33% to go right. This has to be independent from starting point and should only happen by altering the percentage value of left/right dynamically.

No input of any kind allowed, output has to be on the executing console!

For better understanding, here is a readable example in java, that would give you a score of 723:

public class DotJumper{
    public static void main(String[] args){
        int i = (int)(Math.random()*30);
        int max = 29;
        int step = 1;
        int count = 30;
        while(count>0){
            if(i<=1){
                i+=step;
            }else if(i>=max){
                i-=step;
            }else{
                if(Math.random() > 0.5){
                    i+=step;
                }else{
                    i-=step;
                }
            }
            print(i);
            count--;
        }
    }
    public static void print(int i){
        while(i>0){
            System.out.print(' ');
            i--;
        }
        System.out.println('.');
    }
}
share|improve this question
    
In your example, I think that the int i = (int)(Math.random()*30); should be int i = 1 + (int)(Math.random()*29); instead. As is, it generates a number 0 >= x > 30 instead of 0 > x > 30. –  Victor Feb 18 at 17:26
    
I think original code is correct. –  VadimR Feb 18 at 18:15
    
it is correct, because i shift first and the print. so even if the random value exceeds the border, if will first correct and then print. –  Kostronor Feb 18 at 18:17
    
@Kostronor But this implies that the starting dot position does not follows an uniform distribution, the first position is twice as probably than the other positions. OTOH, being uniformly distributed was not a requirement either. –  Victor Feb 18 at 21:41
    
Seems like it would be harder to create a program where the dot jumps around more. So why is there a bonus for restricting its movement? –  Chris Laplante Feb 18 at 23:12

25 Answers 25

APL, 39 – 10 – 50 = –21

0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29

Tested on Dyalog with ⎕IO←1 and ⎕ML←3 but it should be quite portable.

Explanation

                      ?29   take a random natural from 1 to 29
                   31/      repeat it 31 times
  {              }/         reduce (right-fold) the list using the given function:
             ⍵↑''           .  make a string of ⍵ spaces
        '.',⍨               .  append a dot to its right
   ⎕←30↑                    .  right-pad it with spaces up to length 30 and output
   ◇                        .  then
             ?28            .  take a random natural from 1 to 28
          .5+               .  add 0.5, giving a random number ∊ (1.5 2.5 ... 27.5 28.5)
        ⍵>                  .  check whether the result is < ⍵ (see below)
     ¯1*                    .  raise -1 to the boolean result (0 1 become resp. 1 -1)
   ⍵+                       .  add it to ⍵ and return it as the new accumulator value
0/                          finally ignore the numeric result of the reduction

When the current number of spaces is 1 the increment is certainly +1, when it's 29 it's certainly -1; otherwise it's chosen randomly between +1 and -1, with a probability that's a linear interpolation between those extremes. Therefore the dot is always moving and always more likely to move towards the center than towards the sides. If it's exactly in the middle, it has a 50% chance to move to either side.

The reduction of a replication {...}/a/b is just a trick I came up with to repeat some code a-1 times, starting with value b and having the result of each iteration be the right argument of the next. The left arguments are ignored, as is the final result. It turns out to be way shorter than a regular recursive call with guard.

Example run

0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29
                   .          
                    .         
                   .          
                  .           
                 .            
                .             
               .              
                .             
               .              
                .             
               .              
              .               
             .                
              .               
             .                
              .               
               .              
              .               
               .              
                .             
                 .            
                  .           
                 .            
                  .           
                 .            
                  .           
                 .            
                .             
               .              
                .             
share|improve this answer
    
+1 I really like this one! –  Kostronor Feb 17 at 23:58
    
Thanks, I really liked this challenge too! –  Tobia Feb 18 at 0:00
    
apl is a great language for golf (hard to read for me, though); UP! –  blabla999 Feb 18 at 0:27
    
@blabla999 APL has many common symbols and some strange ones, but once you learn their function the language is easy to read and write. Certainly easier that the ASCII noise of 'golfing' languages, but I'd venture to say it's even easier than regular languages. The syntax is very regular, you only have one rule: the expressions are executed from right to left, so that they can be read from left to right: +/2×⍳9 is read "the sum of: two times: the naturals up to 9" but is executed in the opposite way. –  Tobia Feb 18 at 9:27
    
@blabla999 if you want to learn it, I would suggest getting your hands on the classical textbook "APL: An Interactive Approach" by Leonard Gilman and Allen J. Rose (you should be able to find a cheap copy on eBay or in used bookshops) and downloading Nars2000, currently the best open-source implementation. It's for Windows, but it runs fine on Linux and Mac using Wine. –  Tobia Feb 18 at 10:14

Mathematica 138 - 10 - 50 = 78

I'm not posting this because I think it's particularly well golfed, but for other reasons. It uses a Markov Process definition with a transition matrix designed to get the ball "centered".

The use of a Markov process in Mathematica allows us to calculate some useful statistics, as you will see below.

First the code (spaces not needed):

r = Range@28/28;
s = DiagonalMatrix;
ListPlot[RandomFunction[DiscreteMarkovProcess[RandomInteger@#, r~ s ~ -1 + s[29/28- r, 1]], 
                                              #], PlotRange -> #] &@{1, 29}

Some outputs:

Mathematica graphics

The transition matrix I used is:

MatrixPlot[s[r, -1] + s[29/28 - r, 1]]

Mathematica graphics

But as I said, the interesting part is that using DiscreteMarkovProcess[] allows us to grab a good picture of what's happening.

Let's see the probability of the ball being at 15 at any time t starting from a particular random state:

d = DiscreteMarkovProcess[RandomInteger@29, s[r, -1] + s[29/28 - r, 1]];
k[t_] := Probability[x[t] == 15, x \[Distributed] d]
ListLinePlot[Table[k[t], {t, 0, 50}], PlotRange -> All]

Mathematica graphics

You can see it fluctuates between 0 and a value near 0.3, that is because depending on the starting state you can only reach 15 on an odd or even number of steps :)

Now we can do the same thing, but telling Mathematica to consider the statistic starting from all possible initial states. What is the probability of being at 15 after a time t?:

d = DiscreteMarkovProcess[Array[1 &, 29]/29, s[r, -1] + s[29/28 - r, 1]];
k[t_] := Probability[x[t] == 15, x \[Distributed] d]
ListLinePlot[Table[k[t], {t, 0, 100}], PlotRange -> All]

Mathematica graphics

You can see it also oscillates ... why? The answer is simple: in the interval [1, 29] there are more odd than even numbers :)

The oscillation is almost gone if we ask for the probability of the ball being at 14 OR 15:

Mathematica graphics

And you could also ask for the limit (in the Cesaro sense) of the state probabilities:

ListLinePlot@First@MarkovProcessProperties[d, "LimitTransitionMatrix"]

Mathematica graphics

Oh, well, perhaps I deserve some downvotes for such an off-topic answer. Feel free.

share|improve this answer
1  
This isn't the shortest but it's really cool. –  Kasra Rahjerdi Feb 19 at 6:02
    
Upvoted, and now your score is no longer 2,222... –  cormullion Feb 19 at 15:44
    
@cormullion Thanks! You can undo that by downvoting hard:) –  belisarius Feb 19 at 15:46

Bash, score 21 (81 bytes - 50 bonus - 10 bonus)

o=$[RANDOM%28];for i in {D..a};{ printf " %$[o+=1-2*(RANDOM%29<o)]s.%$[28-o]s
";}

In this answer, the dot is "pulled" back to the middle. This can be tested by hardcoding the starting point at 0 or 30.

share|improve this answer
    
Good solution! But please do not hardcode the starting point ;) –  Kostronor Feb 18 at 0:12
1  
@Kostronor - oops - I missed that, and have now fixed it. –  DigitalTrauma Feb 18 at 0:23
2  
save a char by replacing {1..30} by {P..m} –  Geoff Reedy Feb 18 at 5:37
    
What if o is 1 and RANDOM%30 returns 0? And on the next iteration, too? –  VadimR Feb 18 at 13:31
    
@VadimR - I think the boundary conditions are fixed now. –  DigitalTrauma Feb 18 at 19:12

Smalltalk, 161 159 145-60 = 85

all columns are 30chars long (operating in mutable string b);

random movement chance is adjusted by biasing rnd value with p (rnd(0..29)-p), taking the sign (-1/0/1) and then adjusting to (-1/+1) via (-1|1), which is taken as move delta (effectively computes: x sign<=0 ifTrue:-1 ifFalse:1). As ST uses 1-based indexing, I have to adjust all string refs by +1 (plz appreciate the -1|1 bit fiddling hack ;-) ).

p:=((r:=Random)next*29)rounded.(b:=String new:30)at:p+1put:$..0to:29do:[:i|b at:p+1put:$ .p:=(p+(((r next*29)-p)sign-1|1))min:29max:0.b at:p+1put:$..b printCR]

stealing an idea from Ruby version (thanx&Up @fipgr), I can get rid of the min/max check:

p:=((r:=Random)next*29)rounded.(b:=String new:30)at:p+1put:$..1to:30 do:[:i|b at:p+1put:$ .p:=p+((r next-(p/29))sign-1|1).b at:p+1put:$.;printCR]

output: (I have manually added the col-numbers and vertical bars afterwards; the code above does not generate them)

 012345678901234567890123456789
|                     .        |
|                    .         |
|                   .          |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|                 .            |
|                .             |
|               .              |
|                .             |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|               .              |
|                .             |
|               .              |
|                .             |
|               .              |
|              .               |
|               .              |
|              .               |
 012345678901234567890123456789
share|improve this answer

C, 86

Assuming that seeding the rand() function is not required.

k=30;main(i){i=rand()%k;while(k--){printf("%*c\n",i+=i==30?-1:i==1||rand()%2?1:-1,46);}}

Explanation:

In C, in "%*c" the * means that the length of the output will have a minimum length, and this minimum length is determined by the argument of the function call (in this case, it is i+=i==30?-1:i==1||rand()%2?1:-1. The c means the next argument (46) is a character (the dot).

As for the boundary check, I apologise that I forgot about that. I have now added this to the answer, at the cost of 15 chars. The ternary operator works as follows: boolean_condition?value_if_true:value_if_false. Note that in C true is 1 and false is 0.

share|improve this answer
    
Can you expand on what is going on in your code? I'm having trouble understanding how printf("%*c\n",i+=rand()%2?1:-1,46) prints the spaces, as well as how it keeps the dot from possibly moving past 29. Thanks in advance. (Sorry, I'm not a C programmer.) –  fireeyedboy Feb 17 at 23:33
    
@fireeyedboy done, hope you understand :) –  ace Feb 17 at 23:53
    
Aaaah, I kind of had the feeling you were cheating a little bit there. ;-) But the rest is clear indeed now. Thank you! And nice solution! Does C also have the strange behavior with rand()%2 in that it is very predictable (odd/even turns)? I tried your rand()%2 in my PHP solution, and it exhibited this very predictable behavior (as opposed to rand(0,1). Since PHP makes a lot of use of C libraries (if I'm correct) I was wondering whether your C program has the same 'flaw'. –  fireeyedboy Feb 18 at 0:02
    
@fireeyedboy I did not seed the rand() function. In C if rand() is not seeded explicitly, it always uses the same seed every time. That's why it is predictable. If I had to seed it I can do srand(time()); which costs 14 chars –  ace Feb 18 at 0:05
    
But is it so predictable that it switches from odd to even on each subsequent call as well? PHP claims rand() doesn't need to be seeded with srand() anymore, but still shows this odd behavior. –  fireeyedboy Feb 18 at 0:27

Java: 204 183 182 characters - 10 - 50 = 122

class K{public static void main(String[]y){int k,j,i=(int)(29*Math.random());for(j=0;j<30;j++,i+=Math.random()*28>=i?1:-1)for(k=0;k<31;k++)System.out.print(k>29?"\n":k==i?".":" ");}}

First, the dot position must be 0 < x < 30, i.e. [1-29]. This generates a number between 0 and 28 uniformly distributed, and for the puroposes of this program [0-28] has the same effect as [1-29]:

i=(int)(29*Math.random());

I personally prefered if it would be normally distributed around 14, but my answer would be longer:

i=0;for(j=0;j<29;j++)i+=(int)(2*Math.random());

Second, this code ensures that it tends to be in the middle:

i+=Math.random()*28>=i?1:-1

The probability to get +1 is larger as smaller is the value of i, and we have the opposite for -1. If i is 0, the probability of getting +1 is 100%. If i is 28, the probability of getting +1 is 0%.

Third, by replacing the " " at the end by "_" to see the output easier, we see that each line has 30 characters plus a new line:

__________.___________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
____________._________________
_____________.________________
______________._______________
_____________.________________
______________._______________
_______________.______________
______________._______________
_____________.________________

Thanks for @VadimR for pointing out a misunderstanding in a prior version.

share|improve this answer
    
But i getting to 0 is illegal, isn't it? –  VadimR Feb 18 at 16:13
    
@VadimR, for me i is in the range [0-29]. This is equivalent to [1-30] or [288-317], the output would be the same. What matters is that there are 30 integer numbers in the interval [0-29]. –  Victor Feb 18 at 16:46
    
"The number of spaces is the x position of your dot defined with 0 < x < 30" I.e. the number of spaces (or 0-based dot position) is 1..29. i can't be 0. I understand it's all about having fun but still it is sad. –  VadimR Feb 18 at 17:08
    
@VadimR, Oh, thanks. Fixed. This means that the dot will never be in the rightmost posistion, but anyway, that is what was specified. –  Victor Feb 18 at 17:22
    
I'm sorry, but it didn't fix anything. Imagine i gets 1 initially, and on first iteration Math.random() is 0, then i gets 0. Please don't get me wrong, it's not about your answer. Rather about my inability to read most languages other than C-like. Then with no reaction (except for upvotes) about errors, how can I know they are right or not? –  VadimR Feb 18 at 17:40

Ruby 69 66 64-60 = 4

i=rand(30);30.times{a=' '*30;a[i]=?.;puts a;i+=rand>i/29.0?1:-1}

Sample:

            .             
           .              
            .             
           .              
          .               
           .              
            .             
             .            
              .           
             .            
              .           
               .          
              .           
               .          
              .           
             .            
            .             
             .            
              .           
             .            
              .           
             .            
            .             
             .            
            .             
             .            
            .             
           .              
          .               
           .              
share|improve this answer

Mathematica 157-10-50 = 97

A random number from 1-30 is used for starting. All the remaining column numbers from the dot are chosen via RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, which translates to: "If the prior column number was greater than 15, select one number from the set {-1,1}, with -1 weighted 2:1 with respect to 1; otherwise, flip the weights and choose from the same set.

ReplacePart replaces the element in a list of 30 blank spaces that corresponds to the column of interest.

f@c_ := Switch[d = RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, 1, 2, 30, 29, d, d]
Row@ReplacePart[Array["_" &, 29], # -> "."] & /@ NestList[f, RandomInteger@29+1, 30] // TableForm

dot

share|improve this answer
    
Nice use of RandomChoice[] –  belisarius Feb 18 at 17:57

><>, 358 - 10 = 348

This won't win at codegolf, but it works. (On windows 7 with this interpreter, which implements the "p" instruction differently than the esolang page defines it)

1v        >a"                              "v
v<      0<} vooooooooooooooooooooooooooooooo<
&  _>   v : >$" "@p1+:2f*(?v;
  |x1>  v^}!               <
  |xx2> v p
  |xxx3>v  
  |xxxx4v $
>!|xxx< v }
  |xxxx6v }
  |xxx7>v @
  |xx8> v :
  |x9v  < @>  5)?v$:67*)?vv
   _>>&?v!@^     >$:b(?v v
  v }"."< :        v+ 1<  <
  >a+b+00}^0}}${"."< <- 1<

The name of this language can't be googled, so here's its esolang article for the curious.

share|improve this answer
    
Can you code the requirement for the -50 in less than 50 characters? –  Victor Feb 18 at 15:43
1  
@Victor Probably, but ><> is a giant pain to code in (a fun giant pain), so I need to take a break from it. –  SirCxyrtyx Feb 18 at 21:19
    
@SirCxyrtyx this made me chuckle. Well golfed sir. –  Gusdor Feb 19 at 21:17

PHP, 118 113 112 111 (, -10 bonus points = 101)

(second try, with horribly predictable rand() behavior, and a little more efficiency)

for($n=30,$i=rand(1,29),$t=$s=pack("A$n",'');$n--;$i+=$i<2|rand()%2&$i<28?1:-1,$t=$s){$t[$i-1]='.';echo"$t\n";}

Possible result:

______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________

PHP, 130 (, -10 bonus points = 120)

(first try)

This could probably still be much more efficient:

for($n=30,$i=rand(1,29),$t=$s=str_repeat(' ',$n)."\n";$n--;$i=$i<2?2:($i>28?28:(rand(0,1)?$i+1:$i-1)),$t=$s){$t[$i-1]='.';echo$t;}

If I replace the space with an underscore (for display purposes), this is a possible result:

________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_______.______________________
______._______________________
_____.________________________
____._________________________
_____.________________________
____._________________________
___.__________________________

Oddly enough, if I replace rand(0,1) with rand()%2 (PHP 5.4, on Windows XP), the random result always switches from odd to even, and vice versa, on each next iteration, making rand() worryingly predictable, in that sense, all of a sudden. This 'bug' appears to be one that has been known since 2004. Not entirely sure whether it's exactly the same 'bug' though.

share|improve this answer

J 42 characters - 50 -10 = -18

'_.'{~(|.~((I.%<:@#)*@-?@0:))^:(<@#)1=?~30

Explanation, starting from the right (some knowledge about trains comes in handy):

init=: 0=?~30          NB. where is the 0 in the random permutation of [0,29]
rep =: ^:(<@#)         NB. repeat as many times as the array is long, showing each step

rnd =: ?@0:            NB. discards input, generates a random number between 0 and 1

signdiff =: *@-        NB. sign of the difference (because this works nicely with
                       NB. the shift later on).

left_prob =: (I.%<:@#) NB. probability of shifting left. The position of the one (I.) divided by the length -1.

shift =: |.~           NB. x shift y , shifts x by y positions to the left.

output =: {&'_.'       NB. for selecting the dots and bars.

NB. Piecing things together:
output (shift (left_prob signdiff rnd))rep init

Center tendency, -50, example over 1000 runs:

NB. Amounts of ones in each column (sum)
   ]a=:+/ (|.~((I.%<:@#)*@-?@0:))^:(<1000)0=?30
0 0 0 0 0 0 2 6 10 12 25 60 95 121 145 161 148 99 49 27 19 13 6 1 1 0 0 0 0 0
   +/a NB. check the number of ones in total
1000
   |. |:(<.a%10) #"0 1] '*' NB. plot of those values
           *              
           *              
          ***             
          ***             
         ****             
         ****             
         ****             
        ******            
        ******            
        ******            
       *******            
       *******            
       ********           
       ********           
      **********          
    **************        

Example run, outputting exactly 30 bytes each line

_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________
_____________.________________
____________._________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________
share|improve this answer
    
A very good solution! –  Kostronor Feb 19 at 8:56
    
A very good challenge too! –  jpjacobs Feb 19 at 9:19

Java - 198 183 characters

This is just a plain, simple, direct and uncreative golf of the example that you had given in the question.

class A{public static void main(String[]y){int c,j,i=(int)(Math.random()*30);for(c=30;c>0;c--)for(j=i+=i<2?1:i>28?-1:Math.random()>0.5?1:-1;j>=0;j--)System.out.print(j>0?" ":".\n");}}
share|improve this answer

Batch - (288 Bytes - 10) 278

@echo off&setlocal enabledelayedexpansion&set/ap=%random%*30/32768+1&for /l %%b in (1,1,30)do (set/ar=!random!%%2&if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !p! LSS 30 (set/ap+=1)else set/ap-=1
for /l %%c in (1,1,30)do if %%c==!p! (set/p"=."<nul)else set/p"=_"<nul
echo.)

Un-golfed:

@echo off
setlocal enabledelayedexpansion
set /a p=%random%*30/32768+1
for /l %%b in (1,1,30) do (
    set /a r=!random!%%2
    if !r!==1 (
        if !p! GTR 1 (set /a p-=1) else set /a p+=1
    ) else if !p! LSS 30 (set /a p+=1) else set /a p-=1
    for /l %%c in (1,1,30) do if %%c==!p! (set /p "=."<nul) else set /p "=_"<nul
    echo.
)

To output spaces instead of underscores - 372 Bytes -

@echo off&setlocal enabledelayedexpansion&for /f %%A in ('"prompt $H &echo on&for %%B in (1)do rem"')do set B=%%A
set/ap=%random%*30/32768+1&for /l %%b in (1,1,30)do (set/ar=!random!*2/32768+1&if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !p! LSS 30 (set/ap+=1)else set/ap-=1
for /l %%c in (1,1,30)do if %%c==!p! (set/p"=."<nul)else set/p"=.%B% "<nul
echo.)

Looking for some help with the following logic, surely this isn't the most space efficient method (!r! will expand to either 1 or 2) -

if !r!==1 (
    if !p! GTR 1 (set /a p-=1) else set /a p+=1
) else if !p! LSS 30 (set /a p+=1) else set /a p-=1

It golfs down to: if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !r! LSS 30 (set/ap+=1)else set/ap-=1

share|improve this answer

J, 42 characters, no bonuses

' .'{~(i.30)=/~29<.0>.+/\(-0&=)?(,2#~<:)30

Example run:

          ' .'{~(i.30)=/~29<.0>.+/\(-0&=)?(,2#~<:)30
                       .
                      .
                     .
                      .
                     .
                      .
                     .
                      .
                       .
                      .
                     .
                    .
                     .
                    .
                     .
                    .
                     .
                      .
                       .
                        .
                       .
                        .
                       .
                      .
                     .
                      .
                       .
                      .
                     .
                    .
share|improve this answer

Python 2.7 (126 - 10 (fix length) - 50 (Center Tendency) = 66)

The following program have a center tendency over a larger sample

s=id(9)%30
for e in ([[0,2][s>15]]*abs(s-15)+map(lambda e:ord(e)%2*2,os.urandom(30)))[:30]:
    s+=1-e;print" "*s+"."+" "*(28-s)

Demo

         .           
        .            
       .             
      .              
     .               
      .              
       .             
        .            
         .           
          .          
           .         
          .          
           .         
          .          
         .           
        .            
       .             
        .            
       .             
      .              
     .               
      .              
       .             
      .              
     .               
    .                
   .                 
    .                
   .                 
    .              
share|improve this answer
    
Like the s=id(9)%30 for the seeding. os needs importing, though? And does this cover the full 1-30 range? Oh wait...*rereads the inequality at top of page* –  psion5mx Feb 18 at 18:24

Javascript 125 73 72 60 (120 - 50 - 10)

i=0;r=Math.random;s=r()*30|0;do{a=Array(30);a[s=s>28?28:s?r()<s/30?s-1:s+1:1]='.';console.log(a.join(' '))}while(++i<30)

EDIT: Fix for 50 point bonus and 10 point bonus.

EDIT 2: Even shorter!

share|improve this answer
    
can you explain, where you get the 50 points bonus? I am not getting it at the moment... –  Kostronor Feb 18 at 0:15
    
@Kostronor I just saw the edit for the requirement. Looks like I don't get the 50 points yet. –  acbabis Feb 18 at 2:51
    
@acbabis, well done ! You can save some bytes (116) : r=Math.random;s=r()*30|0;for(i=0;i++<30;a=Array(30)){a[s=s>28?28:s?r()<s/30?s-1‌​:s+1:1]='.';console.log(a.join(' '))} –  Michael Feb 18 at 9:27
    
@Michael Thanks for the tips. Couldn't get the array init inside the for working, though; had to use a do while. –  acbabis Feb 18 at 16:58

D - 167, 162, 144 ( 154 - 10 )

Golfed:

import std.stdio,std.random;void main(){int i=uniform(1,30),j,k;for(;k<30;++k){char[30]c;c[i]='.';c.writeln;j=uniform(0,2);i+=i==29?-1:i==0?1:j==1?1:-1;}}

Un-golfed:

import std.stdio, std.random;

void main()
{
    int i = uniform( 1, 30 ), j, k;

    for(; k < 30; ++k )
    {
        char[30] c;
        c[i] = '.';
        c.writeln;
        j = uniform( 0, 2 );
        i += i == 29 ? -1 : i == 0 ? 1 : j == 1 ? 1 : -1;
    }
}

EDIT 1 - I'm not quite sure if my code qualifies for the -50 bonus or not. i doesn't always start in the middle, but during the for loop, the dot never moves more than like 3 places either direction, so when i does start near the middle, the whole thing tends to stay there as well.

EDIT 2 - Code now qualifies for the -10 bonus, as it prints an array of 29 characters followed by LF for a total of exactly 30 chars per line.

share|improve this answer
    
as it prints an array of 29 characters followed by LF - It should be 30 characters followed by a LF. –  Victor Feb 18 at 15:30
    
@Victor ahh, thank you for the correction, I misinterpreted the main post. –  Tony H. Feb 18 at 17:16

Python 2.7: 126-10-50 = 66 109-10-50 = 49

Some great answers here. First attempt in Python, thinking about improvements. Not helped by the need for an import.

-10 - yes 30 chars + \n on each line

-50 - the further away from the centre, the more likely a move the other way (accomplished by building a list with a different number of +/i offsets)

from random import choice;p,l=15,[]
for i in range(30):
 q=29-p;l+=[' '*p+'.'+' '*q];p+=choice([1]*q+[-1]*p)
print'\n'.join(l)

Take 2: Got rid of the hard-coded starting point - now starts at random point. Because of this, I needed randint, so I decided to use that instead of choice for the offset. Used the (-1)**bool trick for that.

from random import randint as r;p=r(0,29)
for i in range(30):
 print' '*p+'.'+' '*(29-p);p+=(-1)**(r(0,29)<p)
share|improve this answer

R, 107 characters - 60 points bonus=47

s=sample;i=s(29,1);for(j in 1:30){a=rep(' ',30);i=i+s(c(-1,1),1,p=c(i-1,29-i));a[i]='.';cat(a,'\n',sep='')}

i is the index of the dot. a is the array of 30 spaces. Starting point is random (uniformly from 1 to 29). At each iteration we randomly add -1 or +1 to i with weighted probabilities: i-1 for -1 and 29-i for +1 (values fed as probabilities don't need to sum to one), meaning that it tends to orient the dot towards the center while preventing it from below 1 or above 29 (since their probability fall to 0 in both case).

Example run with _ instead of spaces for legibility:

> s=sample;i=s(1:30,1);for(j in 1:30){a=rep('_',30);i=i+s(c(-1,1),1,p=c(i-1,29-i));a[i]='.';cat(a,'\n',sep='')}
_______________________.______
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
___________________.__________
____________________._________
___________________.__________
__________________.___________
_________________.____________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________
share|improve this answer
    
If I'm not mistaken reading your code, i can become either 0 or 30, no? –  VadimR Feb 18 at 9:27
    
Yes you're right it can be 30 (not more though), i ll change that. –  plannapus Feb 18 at 9:29
1  
It's fixed now. The probability to go from 1 to 0 or to go from 29 to 30 is now 0. The random starting point is now between 1 and 29. –  plannapus Feb 18 at 9:35
    
Hint: You can save 2 more characters by replacing s(1:29,1) with s(29,1). –  Sven Hohenstein Feb 18 at 17:12
    
@SvenHohenstein you're right I always forget about that one –  plannapus Feb 19 at 7:56

C# 184 - 10 - 50 = 123

using System;namespace d{class P{static void Main(){var r=new Random();int p=r.Next(30);for(int i=0;i<30;i++){Console.WriteLine(".".PadLeft(p+1).PadRight(29));p+=r.Next(30)<p?-1:1;}}}}

Output

space replaced with _ for legibility.

____________.________________
___________._________________
__________.__________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
___________._________________
____________.________________
___________._________________
__________.__________________
___________._________________
share|improve this answer
    
I am pretty sure that it should be possible to get a smaller code in the if...else if...else at the end of you code. Further, your output makes me get some doubt that it tends to be in the middle, but your code seems to be right. –  Victor Feb 18 at 15:42
    
Forgot to update the output when i edited the code. The r.Next(30)<p?-1:1; makes it happen. Not sure you can go smaller with the if statements. switch is big because of the mandatory break / return and the final else requires a default:{} case and that is also long. –  Gusdor Feb 18 at 16:15
    
@Victor thanks for the input. i made some edits. –  Gusdor Feb 18 at 16:20
    
If p is zero, the p+=r.Next(30)<p?-1:1; will always get 1, so no need for the if(p==0). Ditto for p==29. p will never be 30, so you can get rid of the else if. –  Victor Feb 18 at 16:43
    
@Victor grand. ill make those changes. Ta. –  Gusdor Feb 19 at 8:02

k [53 - 10 - 50= -7]

Solution 1

{{a:30#" ";a[x]:".";a}'{x+$[*x<1?!30;1;-1]}\[x;*1?x]}

Usage

{{a:30#" ";a[x]:".";a}'{x+$[*x<1?!30;1;-1]}\[x;*1?x]}30

"      .                       "
"       .                      "
"      .                       "
"       .                      "
"      .                       "
"       .                      "
"        .                     "
"         .                    "
"        .                     "
"         .                    "
"        .                     "
"         .                    "
"          .                   "
"           .                  "
"            .                 "
"             .                "
"              .               "
"               .              "
"              .               "
"             .                "
"            .                 "
"           .                  "
"          .                   "
"         .                    "
"        .                     "
"       .                      "
"        .                     "
"         .                    "
"          .                   "
"         .                    "
"          .                   "

Solution 2

{r::x;{a:r#" ";a[x]:".";a}'{a:r#0b;a[x?r]:1b;x+$[a@*1?r;-1;1]}\[x;*1?x]}[30]
share|improve this answer

PowerShell, 77 - 10 - 50 = 17

$x=random 30
1..30|%{$x+=random(@(-1)*$x+@(1)*(29-$x))
'_'*$x+'.'+'_'*(29-$x)}

Output

_.____________________________
__.___________________________
___.__________________________
____._________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
______._______________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
share|improve this answer

Javascript => 125 (135 - 10)

q=Math.random,p=~~(q()*31)+1;for(i=0;i++<30;){s='',d=j=1;for(;j++<31;)s+=j==p?'.':"_";p+=q()<.5?1:-1;p-=p>28?2:p<2?-2:0;console.log(s)}

Note: Space () replaced with underscore (_) for readability

Comments and advises are welcome.

share|improve this answer
    
Sadly, your solution does not qualify, compare your output with the output of other solutions. Shift the dot by one character. –  Kostronor Feb 18 at 12:23
    
@Kostronor Oh! oh! I am so sorry! I forgot to read that part of the question! I will try to develop a new version soon. Thanks for pointing out! –  Gaurang Tandon Feb 18 at 12:25
    
@Kostronor Program edited. –  Gaurang Tandon Feb 18 at 12:39

JavaScript 127 - 10 (30 character lines) - 50 (shifts toward middle) = 67

I had an epiphany going up the lift to my unit, so I had to get it down before it left my memory...

A little variable positional shuffling and a little creativity for calculating the shift probability indicated by x/t... (Thanks Kostronor for pointing it out!) I now gain the -50 bonus for shift to the middle, and I also made the starting position within the full range of the line, which allowed me to shave two bytes!

z=(j=Array(t=29).join("_"))+"."+j;x=(r=Math.random)()*t;for(i=30;i--;)console.log(z.substr(x=(x+=r()<x/t?-1:1)>t?t:x<0?0:x,30))

....5....0....5....0....5....0 <-- Ruler
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
__.___________________________
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________
share|improve this answer
    
Isn't it that randomness of initial dot position here is limited to 2 or 3 possibilities? And that's what keeping dot in the middle (because of very short number of runs = 30) and therefore worth -50? –  VadimR Feb 18 at 10:34
    
Quoting the OP's text: "Your program starts with a random x position and every turn shifts this position randomly by 1 to the left or right" My code initially is defined at 15+r()*2 which could be anything from 15 to 16.9999999998 or so which could round off to 17. the additional x+=r()<.5?-1:1 throws a little more randomness by bringing it to a range of 14 to 18, so technically a random number which is within the definition of what was asked... By bending that rule, the flip (+1,-1) will in most cases bring it back toward the middle... ;) –  WallyWest Feb 18 at 21:26
    
Well, on the random thing, you got me... It was meant to be 'a random position from all possible positions' but it gives you not much advantage, as the 50 points clearly not apply! Please reread the explanation on this bonus, a fixed 0,5 percent do not get it! –  Kostronor Feb 19 at 9:01
    
Valid point, I'll redo my score accordingly... –  WallyWest Feb 20 at 0:39
    
@Kostonor Code updated with proper solution, updated score accordingly! –  WallyWest Feb 20 at 7:17

PHP

With the centring bonus: 82 - 50 = 32

$i=rand(0,29);for($c=0;$c++<30;rand(0,28)<$i?$i--:$i++)echo pack("A$i",'').".\n";

For this version (old versions below), removed the min/max checking as that's taken care of in the centring code. rand(1,28) becomes important here as it allows for the $i++ to push itself up to 29 (actual max).

edit: unnecessary parenthesis, moved shifting code


Simple algorithm for centring: generates a new number between 0 and 29 and compares it to the current one. Takes advantage of the "probability" of getting a number on the bigger side to draw towards the centre.

Actual result: (line numbering added afterwards)

01|        .
02|       .
03|        .
04|         .
05|          .
06|           .
07|            .
08|           .
09|            .
10|             .
11|              .
12|             .
13|            .
14|             .
15|            .
16|             .
17|            .
18|             .
19|              .
20|               .
21|              .
22|             .
23|              .
24|               .
25|                .
26|               .
27|                .
28|                 .
29|                .
30|               .

Archived:

$i=rand(0,29);for($c=0;$c++<30;){($i<1?$j=1:($i>28?$j=28:$j=rand(0,29)));($j<$i?$i--:$i++);echo pack("A$i",'').".\n";} 119 characters

$i=rand(0,29);for($c=0;$c++<30;){($i<1?$i++:($i>28?$i--:(rand(0,29)<$i?$i--:$i++)));echo pack("A$i",'').".\n";} 112 characters

share|improve this answer
    
I'm a little impressed that I shaved off 49 characters since my first version... –  Yoda Feb 19 at 16:40
    
shaved 44 characters now. Which must mean it was 39 last time. –  Yoda Feb 20 at 10:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.