5
\$\begingroup\$

The challenge is to display and scroll a sine waveform in the least number of characters.

Restrictions:

  • Total height of wave must be at least seven units (characters, pixels, etc).
  • The generated wave must scroll in-place.

Additional Rules/Information:

  • The sine wave must be distinguishable from triangle and square waves.
    • "distinguishable" indicates sampling at least every π/8

Additional Judgement Criteria:

  • Appearance/Quality of the wave
  • Number of periods displayed

Winning entries will have the fewest characters of code and generate a sine wave with the most samples per period.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Could you expand the specification? As it stands, I'm not sure what you're looking for. I'm also not sure what the scoring system is. See the description of on topic questions. \$\endgroup\$ Jun 24, 2013 at 17:52
  • \$\begingroup\$ define "distinguishable". Does it suffice that a triangle wave would produce at least one pixel differently under any rounding mode? \$\endgroup\$ Jun 24, 2013 at 18:17
  • \$\begingroup\$ @FKunecke: If you're simply searching for a tool to plot functions: martin-thoma.com/html5/polynom-interpolation.htm \$\endgroup\$ Jul 2, 2013 at 19:57
  • \$\begingroup\$ Does it have to actually be a sine wave, or does a curve that just looks like a sine wave count as good enough? \$\endgroup\$ Jul 12, 2013 at 13:45

14 Answers 14

14
\$\begingroup\$

Mathematica : 49

Plot[Sin[x+a],{x,0,9},Axes->None]~Animate~{a,0,2Pi}

enter image description here

The flickering is a GIF-produced artifact. Runs smoothly on the screen.

\$\endgroup\$
5
  • 2
    \$\begingroup\$ no flickering here, looks great. perhaps a browser-produced artifact? \$\endgroup\$
    – ardnew
    Jun 25, 2013 at 14:01
  • \$\begingroup\$ Why Axes-> None? I don't see a restriction against the use of axes. \$\endgroup\$
    – DavidC
    Jun 25, 2013 at 20:24
  • 1
    \$\begingroup\$ @DavidCarraher To create the illusion of a continuous scrolling (I don't care too much about winning) \$\endgroup\$ Jun 25, 2013 at 21:01
  • 1
    \$\begingroup\$ @ardnew Probably a poor man's laptop artifact :) \$\endgroup\$ Jun 25, 2013 at 21:05
  • 3
    \$\begingroup\$ Golfed version: Animate[#&@@@Sin@x~Plot~{x,a,a+9},{a,∞}] (40 characters). Less then APL :) \$\endgroup\$
    – ybeltukov
    Jan 7, 2014 at 14:45
13
\$\begingroup\$

APL (46)

{∇⍵+1⊣⎕DL÷9⊣⎕SM∘←↑⍵∘{0,⍵,⍨9+⌈9×1○9÷⍨⍺+⍵}¨⍳79}1

It looks like this, and scrolls to the left: sine

In action: http://frankenstein.d-n-s.org.uk/~marinus/sine.mp4

\$\endgroup\$
10
\$\begingroup\$

Machine code x86 16-bit DOS, 40 bytes

░‼═►h áë←☺‼▀♥▐4┘■▐♀▐♦▀←i;@☺&ê◄■├uσBδ╪

Recorded from dosbox

Or in a more human readable format (typical hugi conventions followed) :

;  40 byte version
; 00000000:  0A 00 B0 13 CD 10 68 00-A0 07 89 1B 01 13 DF 03   ......h.........
; 00000010:  DE 34 D9 FE DE 0C DE 04-DF 1B 69 3B 40 01 26 88   .4........i;@.&.
; 00000020:  11 FE C3 75 E5 42 EB D8                           ...u.B..

;  42 byte version
; 00000000:  0A 00 B0 13 CD 10 68 00-A0 07 89 1B 01 13 DF 03   ......h.........
; 00000010:  DE 34 D9 FE DE 0C DE 04-DF 1B 69 3B 40 01 26 88   .4........i;@.&.
; 00000020:  11 FE C3 75 E5 42 E2 FE-EB D6                     ...u.B....

[bits 16]


newscreen:
 or al,[bx+si]  ; trade off vertical height for # of periods
 mov al,13h
 int 10h
 push 0a000h
 pop es


iter:
 mov word [bp+di],bx
 add word [bp+di],dx
 fild word [bp+di]
 fidiv word [si]
 fsin
 fimul word [si]
 fiadd word [si]
 fistp word [bp+di]
 imul di,word [bp+di],320
 mov [es:di+bx],dl
 inc bl
 jnz iter
 inc dx


delay:
 loop delay  ; can remove this to get 40 bytes, but wont look as good since it scrolls too fast

 jmp newscreen
\$\endgroup\$
3
\$\begingroup\$

q

Quick and very ugly, 119 characters:

o:0;
w:.:["\\c"]1;
.z.ts:{-1@'{@[w#" ";where x=y;:;"0"]}[4-7h$4*sin o rotate(til w)%2*acos -1]'[til 9];o::o+1};
\t 100
\$\endgroup\$
3
\$\begingroup\$

Processing, 99

Really just a butchered version of this.

float i,x,t;void draw(){clear();x=t+=0.02;for(i=0;i<75;ellipse(i++*5,50+sin(x+=0.418879)*25,3,3));}

Try it online!

Could've saved some characters at the cost of an uglier animation. Slightly more readable form:

float i,x,t;

void draw() {
    clear();
    x = t+=0.02;
    for(i=0; i<75; ellipse(i++*5, 50+sin(x+=0.418879)*25, 3, 3));
}

Magic numbers:

  • 0.02 kinda affects the scroll speed
  • 75 is the number of dots
  • 5 is the distance on x-axis
  • 50 is the y-position on screen (default window size is 100).
  • 0.418879 ≈ 2π/75*5
  • 25 is the amplitude
  • 3 is the size of the dots
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You could save a few chars by replacing the ellipse with a simpler point call (which takes only two args, not 4, and paints a single pixel), and just drawing more of them. \$\endgroup\$ Jul 12, 2013 at 13:44
3
\$\begingroup\$

Python 2.7 with Pygame (196 178)

import math,pygame as p
D=p.display
x=0
s=D.set_mode((600,400))
while 1:
 i=0;x+=1;D.flip();s.fill([0]*3)
 while i<600:s.set_at((i,int(200*math.sin((i+x)*.01)+200)),[255]*3);i+=1

Draws in pixels. Went for looks rather than characters.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You could save some (4 I think) characters with import math, pygame as p then use D=p.display. \$\endgroup\$
    – Morwenn
    Jun 27, 2013 at 13:03
3
\$\begingroup\$

Ruby, 105 characters

d=0
loop{s=(1..9).map{" "*79}
79.times{|i|s[(Math.sin((i+d)*Math::PI/16)*4+4.5)][i]=?x}
puts"^[[H",s
d+=1}

The ^[ is a single escape character. (You can enter it with Ctrl-V,Esc in the terminal and Vim or Ctrl-Q,Esc in MCEdit and Emacs.)

The animation is displayed from the 2nd line of top left corner of the terminal and scrolls from right to left at full speed (add sleep 0.1; before the last } to slow it down).

Sample run:

bash-4.4$ ruby -e 'd=0;loop{s=(1..9).map{" "*79};79.times{|i|s[(Math.sin((i+d)*Math::PI/16)*4+4.5)][i]=?x};puts"^[[H",s;d+=1}'
                      xxxxx                           xxxxx                    
                    xx     xx                       xx     xx                  
                  xx         xx                   xx         xx                
                 x             x                 x             x               
x               x               x               x               x              
 x             x                 x             x                 x             
  xx         xx                   xx         xx                   xx         xx
    xx     xx                       xx     xx                       xx     xx  
      xxxxx                           xxxxx                           xxxxx    

Ruby: 115 characters

d=0
while 1
s=(1..9).map{" "*79}
79.times{|i|s[(Math.sin((i+d)*Math::PI/16)*4+4.5)][i]=?x}
$><<"\e[H"+s*$/
d+=1
end

The animation is displayed in the top left corner of the terminal and scrolls from right to left at full speed (add sleep 0.1; before the end keyword to slow it down).

Sample run:

                      xxxxx                           xxxxx
                    xx     xx                       xx     xx
                  xx         xx                   xx         xx
                 x             x                 x             x
x               x               x               x               x
 x             x                 x             x                 x
  xx         xx                   xx         xx                   xx         xx
    xx     xx                       xx     xx                       xx     xx
      xxxxx                           xxxxx                           xxxxx
bash-4.1$ ruby -e 'd=0;while 1;s=(1..9).map{" "*79};79.times{|i|s[(Math.sin((i+d)*Math::PI/16)*4+4.5)][i]=?x};$><<"\e[H"+s*$/;d+=1;end'

(I know, can be shortened by replacing Math::PI/16 with its precalculated value of arbitrary precision. For example to 107 characters by using 0.2 multiplier. But the lower the precision, the uglier the output. May edit it in the future, I just keep it for now.)

\$\endgroup\$
2
\$\begingroup\$

Maple, 42 Characters

This is very easy to do with Maple.

plots[animate](plot,[sin(x+a)],a=0..2*Pi);

What it does enter image description here

\$\endgroup\$
2
\$\begingroup\$

TI-BASIC, 22 bytes

  • Name this prgmA. It eventually overflows the stack by calling itself, throwing an ERR:MEMORY; this can be rectified in exchange for 4 bytes by adding While 1 to the beginning and replacing the prgmA line with End.

  • It works pretty much perfectly, although I'm afraid not much can be done to improve its speed.

  • It's currently the winner by far, but can be 'golfed' to 18 bytes by removing the step argument (,.01) from the For( loop, lowering its "Number of periods displayed" score.

For(A,0,6,.01
ClrDraw
DrawF 7sin(X+A
End
prgmA
\$\endgroup\$
8
  • \$\begingroup\$ For(A,0,E9:ClrDraw:DrawF sin(X+sub(A:End, because only seven pixels are required, not seven graph screen units. You also assumed a window that fits the graph. \$\endgroup\$
    – lirtosiast
    Jun 15, 2015 at 21:01
  • \$\begingroup\$ I counted 24 bytes, by the way. \$\endgroup\$
    – lirtosiast
    Jun 15, 2015 at 21:08
  • \$\begingroup\$ @ThomasKwa what do you mean by sub(A? \$\endgroup\$
    – user39326
    Jun 15, 2015 at 22:21
  • 1
    \$\begingroup\$ @Wright Try it! \$\endgroup\$
    – lirtosiast
    Jun 15, 2015 at 22:30
  • 1
    \$\begingroup\$ I didn't find it, Weregoose did at least four years ago, and by trial and error, or something. \$\endgroup\$
    – lirtosiast
    Jun 16, 2015 at 2:47
2
\$\begingroup\$

C (65)

main(int x){for(;;)printf("%*c\n",(int)(22+20*sin(x++/5.)),'x');}

Note: plots sine wave with X axis vertical and therefore scrolls vertically.

\$\endgroup\$
4
  • \$\begingroup\$ Doesn't this violate the “The generated wave must scroll in-place.” rule? \$\endgroup\$
    – manatwork
    Jun 26, 2013 at 6:34
  • \$\begingroup\$ I suppose it depends what you mean by "in-place" - on a basic text terminal, where the text doesn't get saved as it scrolls off the top of the screen, I would argue that it is effectively scrolling in-place. \$\endgroup\$
    – Paul R
    Jun 26, 2013 at 6:49
  • \$\begingroup\$ For clarification: this does not count; if you were to clear the screen and redraw it each time it exceeds the window height it would qualify. \$\endgroup\$ Jul 1, 2013 at 19:18
  • \$\begingroup\$ OK - you should probably add this additional constraint to your question. I think that leveraging the terminal's scrolling capability is perfectly reasonable but hey, it's your challenge... \$\endgroup\$
    – Paul R
    Jul 1, 2013 at 21:41
1
\$\begingroup\$

JavaScript: 265 characters + 59 HTML

<canvas id=c width=99 height=99></canvas>
<script>
var c=document.getElementById("c");var context=c.getContext("2d");context.beginPath();var s=0;setInterval(function(){c.width=c.width;s++;context.moveTo(0+50,50*Math.sin(s+0)+50);for(var e=1;e<99;e++){context.lineTo(e+50,50*Math.sin(s+50*e)+50)}context.stroke()},50)
</script>

JavaScript (ungolfed)

<canvas id="canvas" width="500" height="99"></canvas>
<script>
var c = document.getElementById("canvas");
var context = c.getContext("2d");
context.beginPath();
var s=0;
setInterval(function(){
    c.width = c.width;
    s++;
    context.moveTo(0+50,50*Math.sin(s+0)+50);
    for(var x=1;x<99;x++){
        context.lineTo(x+50, 50*Math.sin(s+50*x)+50);
    }
    context.stroke();
}, 50);
</script>

See it on http://jsfiddle.net/MartinThoma/uv5Xx/

\$\endgroup\$
3
  • \$\begingroup\$ Cool! But as there is an additional “Appearance/Quality of the wave” criteria, I would change the stepping from s++ to s+=.1. Looks much better that way. Regaring the code size, these 182 characters works for me in Firefox: c=document.getElementById("canvas");d=c.getContext("2d");d.beginPath(s=0);l=50;setInterval(function(){c.width=500;s+=.1;for(x=99;x--;)d.lineTo(x+l,l*Math.sin(s+l*x)+l);d.stroke()},l). \$\endgroup\$
    – manatwork
    Jul 2, 2013 at 18:59
  • \$\begingroup\$ I get Unexpected token ILLEGAL in Chrome and SyntaxError: illegal character in Firefox from your code. \$\endgroup\$ Jul 2, 2013 at 19:54
  • \$\begingroup\$ Indeed. No idea what happened during copy-pasting it. See here, 174 characters: jsfiddle.net/uv5Xx/3 \$\endgroup\$
    – manatwork
    Jul 3, 2013 at 6:55
1
\$\begingroup\$

Processing, 115 chars

This one actually draws a pseudo-sine wave, not an actual sine wave:

int t,i,c;void draw(){clear();beginShape();for(i=-1,c=50;i<6;c=-c)curveVertex(50*i++-t,50+c);endShape();t=t%100+1;}

A more readable version:

int t, i, c;
void draw() {
  clear();
  beginShape();
  for(i=-1, c=50; i<6; c=-c)
    curveVertex(50*i++ - t, 50+c);
  endShape();
  t = t%100 + 1;
}
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 38 bytes

Animate[Plot[Sin[x+a],{x,0,10}],{a,5}]

Non-competeting, uses Mathematica 10

\$\endgroup\$
1
  • \$\begingroup\$ Oh, I'm sorry, I just saw how old the challenge is... I will edit my post \$\endgroup\$
    – CocoaBean
    Feb 18, 2016 at 19:13
0
\$\begingroup\$

SmileBASIC

The rules aren't entirely clear, so I'll post a few different answers:

34 bytes (vertical text):

LOCATE SIN(MILLISEC/9)*9+9,?.EXEC.

(It never specifically says this isn't allowed, but none of the other answers are vertical, so I'm not sure)

43 bytes (horizontal text):

LOCATE,SIN(MILLISEC/9)*9+9?0SCROLL-1,.EXEC.

53 bytes (horizontal graphics):

GPSET 1,SIN(MILLISEC/9)*9+9GCOPY.,0,#R,30,1,0,1
EXEC.
\$\endgroup\$

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