Display Scrolling Waves

5

1

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.

Forest Kunecke

Posted 2013-06-24T17:30:49.353

Reputation: 171

Question was closed 2018-03-09T19:12:28.760

2

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.

– Peter Taylor – 2013-06-24T17:52:23.690

define "distinguishable". Does it suffice that a triangle wave would produce at least one pixel differently under any rounding mode? – John Dvorak – 2013-06-24T18:17:29.217

@FKunecke: If you're simply searching for a tool to plot functions: http://martin-thoma.com/html5/polynom-interpolation.htm

– Martin Thoma – 2013-07-02T19:57:03.923

Does it have to actually be a sine wave, or does a curve that just looks like a sine wave count as good enough? – AJMansfield – 2013-07-12T13:45:39.607

Answers

13

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

marinus

Posted 2013-06-24T17:30:49.353

Reputation: 30 224

14

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.

Dr. belisarius

Posted 2013-06-24T17:30:49.353

Reputation: 5 345

2no flickering here, looks great. perhaps a browser-produced artifact? – ardnew – 2013-06-25T14:01:45.270

Why Axes-> None? I don't see a restriction against the use of axes. – DavidC – 2013-06-25T20:24:55.963

1@DavidCarraher To create the illusion of a continuous scrolling (I don't care too much about winning) – Dr. belisarius – 2013-06-25T21:01:49.327

1@ardnew Probably a poor man's laptop artifact :) – Dr. belisarius – 2013-06-25T21:05:38.347

3Golfed version: Animate[#&@@@Sin@x~Plot~{x,a,a+9},{a,∞}] (40 characters). Less then APL :) – ybeltukov – 2014-01-07T14:45:29.990

10

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

vulture

Posted 2013-06-24T17:30:49.353

Reputation: 101

3

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.

beary605

Posted 2013-06-24T17:30:49.353

Reputation: 3 904

1You could save some (4 I think) characters with import math, pygame as p then use D=p.display. – Morwenn – 2013-06-27T13:03:43.037

3

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.)

manatwork

Posted 2013-06-24T17:30:49.353

Reputation: 17 865

3

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

skeevey

Posted 2013-06-24T17:30:49.353

Reputation: 4 139

3

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

daniero

Posted 2013-06-24T17:30:49.353

Reputation: 17 193

1You 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. – AJMansfield – 2013-07-12T13:44:20.023

2

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.

Paul R

Posted 2013-06-24T17:30:49.353

Reputation: 2 893

Doesn't this violate the “The generated wave must scroll in-place.” rule? – manatwork – 2013-06-26T06:34:51.210

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. – Paul R – 2013-06-26T06:49:57.187

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. – Forest Kunecke – 2013-07-01T19:18:32.910

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... – Paul R – 2013-07-01T21:41:25.690

2

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

Cameron

Posted 2013-06-24T17:30:49.353

Reputation: 997

2

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

M. I. Wright

Posted 2013-06-24T17:30:49.353

Reputation: 849

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. – lirtosiast – 2015-06-15T21:01:54.340

I counted 24 bytes, by the way. – lirtosiast – 2015-06-15T21:08:12.430

@ThomasKwa what do you mean by sub(A? – M. I. Wright – 2015-06-15T22:21:34.803

1@Wright Try it! – lirtosiast – 2015-06-15T22:30:26.190

@ThomasKwa What the hell?! That's amazing, how did you find it? – M. I. Wright – 2015-06-15T22:55:50.580

1I didn't find it, Weregoose did at least four years ago, and by trial and error, or something. – lirtosiast – 2015-06-16T02:47:44.380

Interesting. (KermM said that it was "one of [their] OS disassemblers," although I wouldn't be surprised if it was Weregoose) I wonder if there are any other tricks like this (for instance, using a complex list as Circle()'s fourth argument makes it use a 'fast circle' routine) that we don't know of. – M. I. Wright – 2015-06-16T04:07:53.717

Let us continue this discussion in chat.

– lirtosiast – 2015-06-17T00:11:06.073

1

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/

Martin Thoma

Posted 2013-06-24T17:30:49.353

Reputation: 669

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). – manatwork – 2013-07-02T18:59:24.487

I get Unexpected token ILLEGAL in Chrome and SyntaxError: illegal character in Firefox from your code. – Martin Thoma – 2013-07-02T19:54:10.143

Indeed. No idea what happened during copy-pasting it. See here, 174 characters: http://jsfiddle.net/uv5Xx/3/

– manatwork – 2013-07-03T06:55:39.187

1

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;
}

AJMansfield

Posted 2013-06-24T17:30:49.353

Reputation: 2 758

0

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.

12Me21

Posted 2013-06-24T17:30:49.353

Reputation: 6 110

0

Mathematica, 38 bytes

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

Non-competeting, uses Mathematica 10

CocoaBean

Posted 2013-06-24T17:30:49.353

Reputation: 309

Oh, I'm sorry, I just saw how old the challenge is... I will edit my post – CocoaBean – 2016-02-18T19:13:12.640