use strict;
use warnings;

sub compound_duration {
    my $sec = shift;
    no warnings 'numeric';

    return join ', ', grep { $_ > 0 }
        int($sec/60/60/24/7)    . " wk",
        int($sec/60/60/24) % 7  . " d",
        int($sec/60/60)    % 24 . " hr",
        int($sec/60)       % 60 . " min",
        int($sec)          % 60 . " sec";
}

for (7259, 86400, 6000000) {
    printf "%7d sec  =  %s\n", $_, compound_duration($_)
}


with javascript_semantics
?elapsed(7259)
?elapsed(86400)
?elapsed(6000000)


/* Convert seconds to Compound Duration (weeks, days, hours, minutes, seconds). */

cvt: procedure options (main);			/* 5 August 2015 */
   declare interval float (15);
   declare (unit, i, q controlled) fixed binary;
   declare done bit (1) static initial ('0'b);
   declare name (5) character (4) varying static initial (' wk', ' d', ' hr', ' min', ' sec' );

   get (interval);
   put edit (interval, ' seconds = ') (f(10), a);
   if interval = 0 then do; put skip list ('0 sec'); stop; end;

   do unit = 60, 60, 24, 7;
      allocate q;
      q = mod(interval, unit);
      interval = interval / unit;
   end;
   allocate q; q = interval;
   do i = 1 to 5;
      if q > 0 then
         do;
            if done then put edit (', ') (a);
            put edit (trim(q), name(i)) (a, a); done = '1'b;
         end;
      if i < 5 then free q;
   end;
end cvt;


function Get-Time
{
  <#
    .SYNOPSIS
        Gets a time string in the form: # wk, # d, # hr, # min, # sec
    .DESCRIPTION
        Gets a time string in the form: # wk, # d, # hr, # min, # sec
        (Values of 0 are not displayed in the string.)

        Days, Hours, Minutes or Seconds in any combination may be used
        as well as Start and End dates.

        When used with the -AsObject switch an object containing properties
        similar to a System.TimeSpan object is returned.
    .INPUTS
        DateTime or Int32
    .OUTPUTS
        String or PSCustomObject
    .EXAMPLE
        Get-Time -Seconds 7259
    .EXAMPLE
        Get-Time -Days 31 -Hours 4 -Minutes 8 -Seconds 16
    .EXAMPLE
        Get-Time -Days 31 -Hours 4 -Minutes 8 -Seconds 16 -AsObject
    .EXAMPLE
        Get-Time -Start 3/10/2016 -End 1/20/2017
    .EXAMPLE
        Get-Time -Start (Get-Date) -End (Get-Date).AddSeconds(6000000)
  #>
    [CmdletBinding(DefaultParameterSetName='Date')]
    Param
    (
        # Start date
        [Parameter(Mandatory=$false, ParameterSetName='Date',
                   Position=0)]
        [datetime]
        $Start = (Get-Date),

        # End date
        [Parameter(Mandatory=$false, ParameterSetName='Date',
                   Position=1)]
        [datetime]
        $End = (Get-Date),

        # Days in the time span
        [Parameter(Mandatory=$false, ParameterSetName='Time')]
        [int]
        $Days = 0,

        # Hours in the time span
        [Parameter(Mandatory=$false, ParameterSetName='Time')]
        [int]
        $Hours = 0,

        # Minutes in the time span
        [Parameter(Mandatory=$false, ParameterSetName='Time')]
        [int]
        $Minutes = 0,

        # Seconds in the time span
        [Parameter(Mandatory=$false, ParameterSetName='Time')]
        [int]
        $Seconds = 0,

        [switch]
        $AsObject
    )

    Begin
    {
        [PSCustomObject]$timeObject = "PSCustomObject" |
            Select-Object -Property Weeks,RemainingDays,
                                    Days,Hours,Minutes,Seconds,Milliseconds,Ticks,
                                    TotalDays,TotalHours,TotalMinutes,TotalSeconds,TotalMilliseconds
        [int]$remainingDays  = 0
        [int]$weeks          = 0

        [string[]]$timeString = @()
    }
    Process
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            'Date' { $timeSpan = New-TimeSpan -Start $Start -End $End }
            'Time' { $timeSpan = New-TimeSpan -Days $Days -Hours $Hours -Minutes $Minutes -Seconds $Seconds }
        }

        $weeks = [System.Math]::DivRem($timeSpan.Days, 7, [ref]$remainingDays)

        $timeObject.Weeks             = $weeks
        $timeObject.RemainingDays     = $remainingDays
        $timeObject.Days              = $timeSpan.Days
        $timeObject.Hours             = $timeSpan.Hours
        $timeObject.Minutes           = $timeSpan.Minutes
        $timeObject.Seconds           = $timeSpan.Seconds
        $timeObject.Milliseconds      = $timeSpan.Milliseconds
        $timeObject.Ticks             = $timeSpan.Ticks
        $timeObject.TotalDays         = $timeSpan.TotalDays
        $timeObject.TotalHours        = $timeSpan.TotalHours
        $timeObject.TotalMinutes      = $timeSpan.TotalMinutes
        $timeObject.TotalSeconds      = $timeSpan.TotalSeconds
        $timeObject.TotalMilliseconds = $timeSpan.TotalMilliseconds
    }
    End
    {
        if ($AsObject) { return $timeObject }

        if ($timeObject.Weeks)         { $timeString += "$($timeObject.Weeks) wk"        }
        if ($timeObject.RemainingDays) { $timeString += "$($timeObject.RemainingDays) d" }
        if ($timeObject.Hours)         { $timeString += "$($timeObject.Hours) hr"        }
        if ($timeObject.Minutes)       { $timeString += "$($timeObject.Minutes) min"     }
        if ($timeObject.Seconds)       { $timeString += "$($timeObject.Seconds) sec"     }

        return ($timeString -join ", ")
    }
}


:- use_module(library(clpfd)).

% helper to perform the operation with just a number.
compound_time(N) :-
    times(N, R),
    format('~p: ', N),
    write_times(R).

% write out the results in the 'special' format.
write_times([[Tt, Val]|T]) :-
    dif(T, []),
    format('~w ~w, ', [Val, Tt]),
    write_times(T).
write_times([[Tt, Val]|[]]) :-
    format('~w ~w~n', [Val, Tt]).

% this predicate is the main predicate, it takes either N
% or a list of split values to get N, or both.
times(N, R) :-
    findall(T, time_type(T,_), TTs),
    times(TTs, N, R).

% do the split, if there is a 1 or greater add to a list of results.
times([], _, []).
times([Tt|T], N, Rest) :-
    time_type(Tt, Div),
    Val #= N // Div,
    Val #< 1,
    times(T, N, Rest).
times([Tt|T], N, [[Tt,Val]|Rest]) :-
    time_type(Tt, Div),
    Val #= N // Div,
    Val #>= 1,
    Rem #= N mod Div,
    times(T, Rem, Rest).

% specifify the different time split types
time_type(wk, 60 * 60 * 24 * 7).
time_type(d, 60 * 60 * 24).
time_type(hr, 60 * 60).
time_type(min, 60).
time_type(sec, 1).


EnableExplicit

Procedure.s ConvertSeconds(NbSeconds)
  Protected weeks, days, hours, minutes, seconds
  Protected divisor, remainder
  Protected duration$ = ""
  divisor = 7 * 24 * 60 * 60 ; seconds in a week
  weeks = NbSeconds / divisor
  remainder = NbSeconds % divisor
  divisor / 7 ; seconds in a day
  days = remainder / divisor
  remainder % divisor
  divisor / 24 ; seconds in an hour
  hours = remainder / divisor
  remainder % divisor
  divisor / 60 ; seconds in a minute
  minutes = remainder / divisor
  seconds = remainder % divisor

  If weeks > 0
    duration$ + Str(weeks) + " wk, "
  EndIf

  If days > 0
    duration$ + Str(days) + " d, "
  EndIf

  If hours > 0
    duration$ + Str(hours) + " hr, "
  EndIf

  If minutes > 0
    duration$ + Str(minutes) + " min, "
  EndIf

  If seconds > 0
    duration$ + Str(seconds) + " sec"
  EndIf

  If Right(duration$, 2) = ", "
    duration$ = Mid(duration$, 0, Len(duration$) - 2)
  EndIf

  ProcedureReturn duration$
EndProcedure

If OpenConsole()
  PrintN(ConvertSeconds(7259))
  PrintN(ConvertSeconds(86400))
  PrintN(ConvertSeconds(6000000))
  PrintN("")
  PrintN("Press any key to close the console")
  Repeat: Delay(10) : Until Inkey() <> ""
  CloseConsole()
EndIf


>>> def duration(seconds):
	t= []
	for dm in (60, 60, 24, 7):
		seconds, m = divmod(seconds, dm)
		t.append(m)
	t.append(seconds)
	return ', '.join('%d %s' % (num, unit)
			 for num, unit in zip(t[::-1], 'wk d hr min sec'.split())
			 if num)

>>> for seconds in [7259, 86400, 6000000]:
	print("%7d sec = %s" % (seconds, duration(seconds)))

   7259 sec = 2 hr, 59 sec
  86400 sec = 1 d
6000000 sec = 9 wk, 6 d, 10 hr, 40 min
>>>


  [ ' [ 60 60 24 7 ]
    witheach [ /mod swap ]
    $ ""
    ' [ $ " wk, "  $ " d, "
        $ " hr, "  $ " min, "
        $ " sec, " ]
    witheach
      [ do rot dup iff
          [ number$
            swap join join ]
        else 2drop ]
     -2 split drop ]          is duration$ ( n--> $ )

  ' [ 7259 86400 6000000 ]
  witheach
    [ dup echo
      say " seconds is "
      duration$ echo$
      say "." cr ]


#lang racket/base
(require racket/string
         racket/list)

(define (seconds->compound-durations s)
  (define-values (w d.h.m.s)
    (for/fold ((prev-q s) (rs (list))) ((Q (in-list (list 60 60 24 7))))
      (define-values (q r) (quotient/remainder prev-q Q))
      (values q (cons r rs))))
  (cons w d.h.m.s))

(define (maybe-suffix v n)
  (and (positive? v)
       (format "~a ~a" v n)))

(define (seconds->compound-duration-string s)
  (string-join (filter-map maybe-suffix
                           (seconds->compound-durations s)
                           '("wk" "d" "hr" "min" "sec"))
               ", "))

(module+ test
  (require rackunit)
  (check-equal? (seconds->compound-durations 7259)    (list 0 0  2  0 59))
  (check-equal? (seconds->compound-durations 86400)   (list 0 1  0  0  0))
  (check-equal? (seconds->compound-durations 6000000) (list 9 6 10 40  0))

  (check-equal? (seconds->compound-duration-string 7259)    "2 hr, 59 sec")
  (check-equal? (seconds->compound-duration-string 86400)   "1 d")
  (check-equal? (seconds->compound-duration-string 6000000) "9 wk, 6 d, 10 hr, 40 min"))

;; Tim Brown 2015-07-21


sub compound-duration ($seconds) {
    ($seconds.polymod(60, 60, 24, 7) Z <sec min hr d wk>)
    .grep(*[0]).reverse.join(", ")
}

# Demonstration:

for 7259, 86400, 6000000 {
    say "{.fmt: '%7d'} sec  =  {compound-duration $_}";
}


/* REXX ---------------------------------------------------------------
* Format seconds into a time string
*--------------------------------------------------------------------*/
Call test 7259    ,'2 hr, 59 sec'
Call test 86400   ,'1 d'
Call test 6000000 ,'9 wk, 6 d, 10 hr, 40 min'
Call test 123.50  ,'2 min, 3.5 sec'
Call test 123.00  ,'2 min, 3 sec'
Call test 0.00    ,'0 sec'
Exit

test:
  Parse arg secs,xres
  res=sec2ct(secs)
  Say res
  If res<>xres Then Say '**ERROR**'
  Return

sec2ct:
Parse Arg s
/*
m=s%60; s=s//60
h=m%60; m=m//60
d=h%24; h=h//24
w=d%7;  d=d//7
*/
If s=0 Then Return '0 sec'
Parse Value split(s,60) with m s
Parse Value split(m,60) with h m
Parse Value split(h,24) with d h
Parse Value split(d, 7) with w d
ol=''
If w>0 Then ol=ol w 'wk,'
If d>0 Then ol=ol d 'd,'
If h>0 Then ol=ol h 'hr,'
If m>0 Then ol=ol m 'min,'
If s>0 Then ol=ol (s/1) 'sec'
ol=strip(ol)
ol=strip(ol,,',')
Return ol

split: Procedure
  Parse Arg what,how
  a=what%how
  b=what//how
  Return a b


sec = 6000005
week = floor(sec/60/60/24/7)
if week > 0 see sec
   see " seconds is " + week + " weeks " ok
day = floor(sec/60/60/24) % 7
if day > 0 see day
   see " days " ok
hour = floor(sec/60/60) % 24
if hour > 0 see hour
   see " hours " ok
minute = floor(sec/60) % 60
if minute > 0 see minute
   see " minutes " ok
second = sec % 60
if second > 0 see second
   see " seconds" + nl ok


MINUTE = 60
HOUR   = MINUTE*60
DAY    = HOUR*24
WEEK   = DAY*7

def sec_to_str(sec)
  w, rem = sec.divmod(WEEK)
  d, rem = rem.divmod(DAY)
  h, rem = rem.divmod(HOUR)
  m, s   = rem.divmod(MINUTE)
  units  = ["#{w} wk", "#{d} d", "#{h} h", "#{m} min", "#{s} sec"]
  units.reject{|str| str.start_with?("0")}.join(", ")
end

[7259, 86400, 6000000].each{|t| puts "#{t}\t: #{sec_to_str(t)}"}


sec = 6000005
week	= int(sec/60/60/24/7)
day	= int(sec/60/60/24) mod 7
hour	= int(sec/60/60) mod 24
minute	= int(sec/60) mod 60
second	= sec mod 60

print sec;" seconds is ";
if week > 0 then print week;" weeks ";
if day > 0 then print day;" days ";
if hour > 0 then print hour;" hours ";
if minute > 0 then print minute;" minutes ";
if second > 0 then print second;" seconds"


use std::fmt;

struct CompoundTime {
    w: usize,
    d: usize,
    h: usize,
    m: usize,
    s: usize,
}

macro_rules! reduce {
    ($s: ident, $(($from: ident, $to: ident, $factor: expr)),+) => {{
        $(
            $s.$to += $s.$from / $factor;
            $s.$from %= $factor;
        )+
    }}
}

impl CompoundTime {
    #[inline]
    fn new(w: usize, d: usize, h: usize, m: usize, s: usize) -> Self{
        CompoundTime { w: w, d: d, h: h, m: m, s: s, }
    }

    #[inline]
    fn balance(&mut self) {
        reduce!(self, (s, m, 60), (m, h, 60),
                      (h, d, 24), (d, w, 7));
    }
}

impl fmt::Display for CompoundTime {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}w {}d {}h {}m {}s",
               self.w, self.d, self.h, self.m, self.s)
    }
}

fn main() {
    let mut ct = CompoundTime::new(0,3,182,345,2412);
    println!("Before: {}", ct);
    ct.balance();
    println!("After: {}", ct);
}


//Converting Seconds to Compound Duration

object seconds{
	def main( args:Array[String] ){

		println("Enter the no.")
		val input = scala.io.StdIn.readInt()

		var week_r:Int = input % 604800
		var week:Int = (input - week_r)/604800

		var day_r:Int = week_r % 86400
		var day:Int = (week_r - day_r)/86400

		var hour_r:Int = day_r % 3600
		var hour:Int = (day_r - hour_r)/3600

		var minute_r:Int = hour_r % 60
		var minute:Int = (hour_r - minute_r)/60

		var sec:Int = minute_r % 60

		println("Week = " + week)
		println("Day = " + day)
		println("Hour = " + hour)
		println("Minute = " + minute)
		println("Second = " + sec)
	}
}


(import (scheme base)
        (scheme write)
        (srfi 1)
        (only (srfi 13) string-join))

(define *seconds-in-minute* 60)
(define *seconds-in-hour* (* 60 *seconds-in-minute*))
(define *seconds-in-day* (* 24 *seconds-in-hour*))
(define *seconds-in-week* (* 7 *seconds-in-day*))

(define (seconds->duration seconds)
  (define (format val unit)
    (if (zero? val) "" (string-append (number->string val) " " unit)))
  (let*-values (((weeks wk-remainder) (floor/ seconds *seconds-in-week*))
                ((days dy-remainder) (floor/ wk-remainder *seconds-in-day*))
                ((hours hr-remainder) (floor/ dy-remainder *seconds-in-hour*))
                ((minutes mn-remainder) (floor/ hr-remainder *seconds-in-minute*)))
               (string-join (delete ""
                                    (list (format weeks "wk")
                                          (format days "d")
                                          (format hours "hr")
                                          (format minutes "min")
                                          (format mn-remainder "sec"))
                                    string=?) ", ")))

(display (seconds->duration 7259)) (newline)
(display (seconds->duration 86400)) (newline)
(display (seconds->duration 6000000)) (newline)


func polymod(n, *divs) {
    gather {
        divs.each { |i|
            var m = take(n % i)
            (n -= m) /= i
        }
        take(n)
    }
}

func compound_duration(seconds) {
    (polymod(seconds, 60, 60, 24, 7) ~Z <sec min hr d wk>).grep { |a|
        a[0] > 0
    }.reverse.map{.join(' ')}.join(', ')
}

[7259, 86400, 6000000].each { |s|
    say "#{'%7d' % s} sec  =  #{compound_duration(s)}"
}


local
  fun fmtNonZero (0, _, list) = list
    | fmtNonZero (n, s, list) = Int.toString n ^ " " ^ s :: list
  fun divModHead (_, []) = []
    | divModHead (d, head :: tail) = head div d :: head mod d :: tail
in
  fun compoundDuration seconds =
    let
      val digits = foldl divModHead [seconds] [60, 60, 24, 7]
      and units = ["wk", "d", "hr", "min", "sec"]
    in
      String.concatWith ", " (ListPair.foldr fmtNonZero [] (digits, units))
    end
end

val () = app (fn s => print (compoundDuration s ^ "\n")) [7259, 86400, 6000000]


func duration (_ secs:Int) -> String {
    if secs <= 0 { return "" }
    let units = [(604800,"wk"), (86400,"d"), (3600,"hr"),  (60,"min")]
    var secs = secs
    var result = ""
    for (period, unit) in units {
        if secs >= period {
            result +=  "\(secs/period) \(unit), "
            secs = secs % period
        }
    }
    if secs == 0 {
        result.removeLast(2) // remove ", "
    } else {
        result += "\(secs) sec"
    }
    return result
}

print(duration(7259))
print(duration(86400))
print(duration(6000000))


proc sec2str {i} {
    set factors {
        sec 60
        min 60
        hr  24
        d   7
        wk  Inf
    }
    set result ""
    foreach {label max} $factors {
        if {$i >= $max} {
            set r [expr {$i % $max}]
            set i [expr {$i / $max}]
            if {$r} {
                lappend result "$r $label"
            }
        } else {
            if {$i > 0} {
                lappend result "$i $label"
            }
            break
        }
    }
    join [lreverse $result] ", "
}

proc check {cmd res} {
    set r [uplevel 1 $cmd]
    if {$r eq $res} {
        puts "Ok! $cmd \t = $res"
    } else {
        puts "ERROR: $cmd = $r \t expected $res"
    }
}

check {sec2str 7259}    {2 hr, 59 sec}
check {sec2str 86400}   {1 d}
check {sec2str 6000000} {9 wk, 6 d, 10 hr, 40 min}


Proc _CompoundDuration(7259)
Proc _CompoundDuration(86400)
Proc _CompoundDuration(6000000)

End

_CompoundDuration Param(1)             ' Print compound seconds
  [email protected] = FUNC(_Compound([email protected], 604800, _wk))
  [email protected] = FUNC(_Compound([email protected], 86400, _d))
  [email protected] = FUNC(_Compound([email protected], 3600, _hr))
  [email protected] = FUNC(_Compound([email protected], 60, _min))

  If [email protected] > 0 Then Print [email protected];" sec";      ' Still seconds left to print?
  Print
Return

_Compound Param(3)
  Local(1)

  [email protected] = [email protected]/[email protected]                           ' Get main component
  [email protected] = [email protected]%[email protected]                           ' Leave the rest

  If [email protected] > 0 Then                       ' Print the component
    Print [email protected];
    Proc [email protected]

    If [email protected] > 0 Then
      Print ", ";                      ' If something follows, take
    EndIf                              ' care of the comma
  EndIf
Return ([email protected])

_wk  Print " wk";  : Return
_d   Print " d";   : Return
_hr  Print " hr";  : Return
_min Print " min"; : Return


Private Function compound_duration(ByVal seconds As Long) As String
    minutes = 60
    hours = 60 * minutes
    days_ = 24 * hours
    weeks = 7 * days_
    Dim out As String
    w = seconds \ weeks
    seconds = seconds - w * weeks
    d = seconds \ days_
    seconds = seconds - d * days_
    h = seconds \ hours
    seconds = seconds - h * hours
    m = seconds \ minutes
    s = seconds Mod minutes
    out = IIf(w > 0, w & " wk, ", "") & _
        IIf(d > 0, d & " d, ", "") & _
        IIf(h > 0, h & " hr, ", "") & _
        IIf(m > 0, m & " min, ", "") & _
        IIf(s > 0, s & " sec", "")
    If Right(out, 2) = ", " Then
        compound_duration = Left(out, Len(out) - 2)
    Else
        compound_duration = out
    End If
End Function

Public Sub cstcd()
    Debug.Print compound_duration(7259)
    Debug.Print compound_duration(86400)
    Debug.Print compound_duration(6000000)
End Sub


Function compound_duration(n)
	Do Until n = 0
		If n >= 604800 Then
			wk = Int(n/604800)
			n = n-(604800*wk)
			compound_duration = compound_duration & wk & " wk"
		End If
		If n >= 86400 Then
			d = Int(n/86400)
			n = n-(86400*d)
			If wk > 0 Then compound_duration = compound_duration & ", " End If
			compound_duration = compound_duration & d & " d"
		End If
		If n >= 3600 Then
			hr = Int(n/3600)
			n = n-(3600*hr)
			If d > 0 Then compound_duration = compound_duration & ", " End If
			compound_duration = compound_duration & hr & " hr"
		End If
		If n >= 60 Then
			min = Int(n/60)
			n = n-(60*min)
			If hr > 0 Then compound_duration = compound_duration & ", " End If
			compound_duration = compound_duration & min & " min"
		End If
		If n > 0 Then
			If min > 0 Then compound_duration = compound_duration & ", " End If
			compound_duration = compound_duration & ", " & n & " sec"
			n = 0
		End If
	Loop
End Function

'validating the function
WScript.StdOut.WriteLine compound_duration(7259)
WScript.StdOut.WriteLine compound_duration(86400)
WScript.StdOut.WriteLine compound_duration(6000000)


var duration = Fn.new { |s|
    if (s < 1) return "0 sec"
    var dur = ""
    var divs = [7, 24, 60, 60, 1]
    var units = ["wk", "d", "hr", "min", "sec"]
    var t = divs.reduce { |prod, div| prod * div }
    for (i in 0...divs.count) {
        var u = (s/t).floor
        if (u > 0) {
            dur = dur + "%(u) %(units[i]), "
            s = s % t
        }
        t = t / divs[i]
    }
    if (dur.endsWith(", ")) dur = dur[0..-3]
    return dur
}

for (s in [7259, 86400, 6000000]) System.print(duration.call(s))


char Str(80);
func Duration(Sec); \Convert seconds to compound duration
int  Sec, Amt, Unit, DoComma, I, Quot;
[Amt:= [7*24*60*60, 24*60*60, 60*60, 60, 1];
Unit:= [" wk", " d", " hr", " min", " sec"];
DoComma:= false;
for I:= 0 to 4 do
    [Quot:= Sec/Amt(I);
    Sec:= rem(0);
    if Quot # 0 then
        [if DoComma then Text(8, ", ");
        DoComma:= true;
        IntOut(8, Quot);
        Text(8, Unit(I));
        ];
    ];
ChOut(8, $0D);  ChOut(8, $8A);  \terminating CR+LF
I:= 0;
loop    [Str(I):= ChIn(8);
        if Str(I) >= $80 then return Str;
        I:= I+1;
        ];
];

[Text(0, Duration(7259));
 Text(0, Duration(86400));
 Text(0, Duration(6_000_000));
]


fcn toWDHMS(sec){  //-->(wk,d,h,m,s)
   r,b:=List(),0;
   foreach u in (T(60,60,24,7)){
      sec,b=sec.divr(u);   // aka divmod
      r.append(b);
   }
   r.append(sec).reverse()
}


10 LET m=60: LET h=60*m: LET d=h*24: LET w=d*7
20 DATA 10,7259,86400,6000000,0,1,60,3600,604799,604800,694861
30 READ n
40 FOR i=1 TO n
50 READ s
60 LET nweek=0: LET nday=0: LET nhour=0: LET nmin=0: LET nsec=0: LET s$=""
70 PRINT s;" = ";
80 IF s>=w THEN LET nweek=INT (s/w): LET s=FN m(s,w)
90 IF s>=d THEN LET nday=INT (s/d): LET s=FN m(s,d)
100 IF s>=h THEN LET nhour=INT (s/h): LET s=FN m(s,h)
110 IF s>=m THEN LET nmin=INT (s/m): LET s=FN m(s,m)
120 LET nsec=INT (s)
130 IF nweek>0 THEN LET s$=s$+STR$ nweek+" wk, "
140 IF nday>0 THEN LET s$=s$+STR$ nday+" d, "
150 IF nhour>0 THEN LET s$=s$+STR$ nhour+" hr, "
160 IF nmin>0 THEN LET s$=s$+STR$ nmin+" min, "
170 IF nsec>0 THEN LET s$=s$+STR$ nsec+" sec"
180 IF s$<>"" THEN IF s$(LEN s$-1)="," THEN LET s$=s$( TO LEN s$-2)
190 PRINT s$
200 NEXT i
210 STOP
220 DEF FN m(a,b)=a-INT (a/b)*b


F print_circle(lo, hi, ndots)
   V canvas = [[0B] * (2*hi+1)] * (2*hi+1)
   V i = 0
   L i < ndots
      V x = random:(-hi..hi)
      V y = random:(-hi..hi)
      I x^2 + y^2 C lo^2 .. hi^2
         canvas[x + hi][y + hi] = 1B
         i++

   L(i) 0 .. 2*hi
      print(canvas[i].map(j -> I j {‘♦ ’} E ‘  ’).join(‘’))

print_circle(10, 15, 100)


PROC DrawCircle(BYTE rmin,rmax,max,x0,y0)
  BYTE count,limit
  INT x,y,r2,rmin2,rmax2

  limit=rmax*2+1
  rmin2=rmin*rmin
  rmax2=rmax*rmax
  count=0
  WHILE count<max
  DO
    x=Rand(limit) y=Rand(limit)
    x==-rmax y==-rmax
    r2=x*x+y*y
    IF r2>=rmin2 AND r2<=rmax2 THEN
      Plot(x+x0,y+y0)
      count==+1
    FI
  OD
RETURN

PROC Main()
  BYTE CH=$02FC,COLOR0=$02C4

  Graphics(5+16)
  Color=1
  COLOR0=$0C

  DrawCircle(10,15,100,40,24)

  DO UNTIL CH#$FF OD
  CH=$FF
RETURN


with Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Circle is
   -- extreme coordinate values are -15:0, 15:0, 0:-15, 0:15
   subtype Coordinate is Integer range -15 .. 15;
   type Point is record
      X, Y : Coordinate;
   end record;
   type Point_List is array (Positive range <>) of Point;

   function Acceptable (Position : Point) return Boolean is
      Squared_Sum : Natural := Position.X ** 2 + Position.Y ** 2;
   begin
      return 10 ** 2 <= Squared_Sum and Squared_Sum <= 15 ** 2;
   end Acceptable;

   -- first algorithm
   function Generate_Random_Points
     (Count : Positive := 100)
      return  Point_List
   is
      package RNG is new Ada.Numerics.Discrete_Random (Coordinate);
      Generator  : RNG.Generator;
      Next_Point : Point;
      Result     : Point_List (1 .. Count);
   begin
      RNG.Reset (Generator);
      for N in Result'Range loop
         loop
            Next_Point.X := RNG.Random (Generator);
            Next_Point.Y := RNG.Random (Generator);
            exit when Acceptable (Next_Point);
         end loop;
         Result (N) := Next_Point;
      end loop;
      return Result;
   end Generate_Random_Points;

   -- second algorithm
   function Choose_Precalculated
     (Count : Positive := 100)
      return  Point_List
   is
      subtype Possible_Points is Positive range 1 .. 404;
      package RNG is new Ada.Numerics.Discrete_Random (Possible_Points);
      Generator  : RNG.Generator;
      Point_Pool : Point_List (Possible_Points);
      Next_Point : Point;
      Next_Index : Possible_Points := 1;
      Result     : Point_List (1 .. Count);
   begin
      -- precalculate
      Precalculate : for X in Coordinate'Range loop
         Next_Point.X := X;
         for Y in Coordinate'Range loop
            Next_Point.Y := Y;
            if Acceptable (Next_Point) then
               Point_Pool (Next_Index) := Next_Point;
               exit Precalculate when Next_Index = Possible_Points'Last;
               Next_Index := Next_Index + 1;
            end if;
         end loop;
      end loop Precalculate;
      -- choose
      RNG.Reset (Generator);
      for N in Result'Range loop
         Result (N) := Point_Pool (RNG.Random (Generator));
      end loop;
      return Result;
   end Choose_Precalculated;

   procedure Print_Points (Points : Point_List) is
      Output_String : array (Coordinate, Coordinate) of Character :=
        (others => (others => ' '));
   begin
      for N in Points'Range loop
         Output_String (Points (N).X, Points (N).Y) := '*';
      end loop;
      for Line in Output_String'Range (2) loop
         for Column in Output_String'Range (1) loop
            Ada.Text_IO.Put (Output_String (Column, Line));
         end loop;
         Ada.Text_IO.New_Line;
      end loop;
   end Print_Points;

   My_Circle_Randomly      : Point_List := Generate_Random_Points;
   My_Circle_Precalculated : Point_List := Choose_Precalculated;
begin
   Ada.Text_IO.Put_Line ("Randomly generated:");
   Print_Points (My_Circle_Randomly);
   Ada.Text_IO.Put_Line ("Chosen from precalculated:");
   Print_Points (My_Circle_Precalculated);
end Circle;


PROC clrscr = VOID:
        printf(($g"[2J"$,REPR 27)); # ansi.sys #

PROC gotoxy = (INT x,y)VOID:
        printf(($g"["g(0)";"g(0)"H"$,REPR 27, y,x)); # ansi.sys #

MODE POINT = STRUCT(
    INT x,y
);

INT radius = 15;
INT inside radius = 10;

POINT center = (radius+1, radius+1);

FLEX[0]POINT set;

PROC swap with last set = (INT position,INT where last set)VOID:
(
        INT temp := x OF set[position];
        x OF set[position]:=x OF set[where last set];
        x OF set[where last set] := temp;

        temp := y OF set[position];
        y OF set[position]:=y OF set[where last set];
        y OF set[where last set] := temp
);

PROC create set = VOID:
(
        set := HEAP[(2*radius+1)**2]POINT;
        INT x,y,i:=LWB set;

        FOR x FROM -radius TO radius DO
                FOR y FROM -radius TO radius DO
                        IF sqrt(x*x+y*y)>=inside radius AND sqrt(x*x+y*y)<=radius THEN
                                x OF set[i] := x;
                                y OF set[i] := y;
                                i+:=1
                        FI
                OD
        OD;

        set:=set[:i-1]
);

PROC plot fuzzy set = (CHAR ch)VOID:
(
        INT pos,i;

        TO UPB set DO
                pos := ENTIER(random * UPB set) + 1;

                gotoxy(x OF center + x OF set[pos],y OF center + y OF set[pos]);

                print(ch);

                swap with last set(pos,UPB set)

        OD
);

main:
(
        # srand((INT)time(NIL)); #

        clrscr;
        create set;
        plot fuzzy set("*");
        gotoxy(2*radius+1, 2*radius+1);
        newline(stand in)
)


z=100 ; x = x-coord; y = y-coord; z = count; pBitmap = a pointer to the image; f = filename

pToken	:= Gdip_Startup()
pBitmap := Gdip_CreateBitmap(31, 32)

While z
{
	Random, x, -20, 20
	Random, y, -20,20
	If ( t := sqrt(x**2 + y**2) ) >= 10 && t <= 15
		Gdip_SetPixel(pBitmap, x+15, y+16, 255<<24), z--
}

Gdip_SaveBitmapToFile(pBitmap, f := A_ScriptDir "\ahk_fuzzycircle.png")
run % f

Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)


graphsize 31, 31

for i = 1 to 100
    do
	x = int(rand * 30) - 15
	y = int(rand * 30) - 15
	r = sqr(x*x + y*y)
    until 10 <= r and r <= 15
    color rgb(255, 0, 0)
    plot(x+15, y+15)
next i
end


#include <stdio.h>
#include <stdlib.h>

inline
int randn(int m)
{
	int rand_max = RAND_MAX - (RAND_MAX % m);
	int r;
	while ((r = rand()) > rand_max);
	return r / (rand_max / m);
}

int main()
{
	int i, x, y, r2;
	unsigned long buf[31] = {0}; /* could just use 2d array */

	for (i = 0; i < 100; ) {
		x = randn(31) - 15;
		y = randn(31) - 15;
		r2 = x * x + y * y;
		if (r2 >= 100 && r2 <= 225) {
			buf[15 + y] |= 1 << (x + 15);
			i++;
		}
	}

	for (y = 0; y < 31; y++) {
		for (x = 0; x < 31; x++)
			printf((buf[y] & 1 << x) ? ". " : "  ");
		printf("\n");
	}

	return 0;
}


using System;
using System.Diagnostics;
using System.Drawing;

namespace RosettaConstrainedRandomCircle
{
    class Program
    {
        static void Main(string[] args)
        {
            var points = new Point[404];
            int i = 0;
            for (int y = -15; y <= 15; y++)
                for (int x = -15; x <= 15 && i < 404; x++)
                {
                    var c = Math.Sqrt(x * x + y * y);
                    if (10 <= c && c <= 15)
                    {
                        points[i++] = new Point(x, y);
                    }
                }

            var bm = new Bitmap(600, 600);
            var g = Graphics.FromImage(bm);
            var brush = new SolidBrush(Color.Magenta);

            var r = new System.Random();
            for (int count = 0; count < 100; count++)
            {
                var p = points[r.Next(404)];
                g.FillEllipse(brush, new Rectangle(290 + 19 * p.X, 290 + 19 * p.Y, 10, 10));
            }
            const string filename = "Constrained Random Circle.png";
            bm.Save(filename);
            Process.Start(filename);
        }
    }
}


(ns rosettacode.circle-random-points
  (:import [java.awt Color Graphics Dimension]
           [javax.swing JFrame JPanel]))

(let [points (->> (for [x (range -15 16), y (range -15 16)
			:when (<= 10 (Math/hypot x y) 15)]
		    [(+ x 15) (+ y 15)])
		  shuffle
		  (take 100))]
  (doto (JFrame.)
    (.add (doto (proxy [JPanel] []
		  (paint [^Graphics g]
                    (doseq [[x y] points]
                      (.fillRect g (* 10 x) (* 10 y) 10 10))))
	    (.setPreferredSize (Dimension. 310 310))))
    (.setResizable false)
    (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
    .pack
    .show))


       identification division.
       program-id. circle.
       environment division.
       input-output section.
       file-control.
           select plot-file assign "circle.txt".
       data division.
       file section.
       fd plot-file report plot.
       working-storage section.
       1 binary.
        2 seed pic 9(18).
        2 x pic s9(4).
        2 y pic s9(4).
        2 i pic 9(4).
        2 dot-count pic 9(4) value 0.
        2 dot-count-save pic 9(4) value 0.
        2 temp-points.
         3 pic s9(4) occurs 2.
        2 xy-table.
         3 point-pair occurs 0 to 404 depending dot-count.
          4 x-point pic s9(4).
          4 y-point pic s9(4).
       1 plot-table value all "0".
        2 occurs 31.
         3 dot pic 9 occurs 31.
       1 cur-date-time.
        2 yyyymmdd pic 9(8).
        2 hh pic 9(2).
        2 mm pic 9(2).
        2 ss pic 9(2).
       1 plot-work.
        2 plot-item pic xb occurs 31.
       report section.
       rd plot.
       1 plot-line type de.
        2 line plus 1.
         3 column is 1 source is plot-work pic x(62).
       procedure division.
       begin.
           perform compute-seed
           perform find-all-valid-points
           perform shuffle-point-pairs
           perform select-100-dots
           perform print-dots
           stop run
           .

       find-all-valid-points.
           perform varying x from -15 by 1 until x > +15
               perform varying y from -15 by 1 until y > +15
                   if (function sqrt (x ** 2 + y ** 2))
                       >= 10 and <= 15
                   then
                       move 1 to dot (x + 16 y + 16)
                       add 1 to dot-count
                       compute x-point (dot-count) = x + 16
                       compute y-point (dot-count) = y + 16
                   end-if
               end-perform
           end-perform
           display "Total points: " dot-count
           .

       shuffle-point-pairs.
           move dot-count to dot-count-save
           compute i = function random (seed) * dot-count + 1
           perform varying dot-count from dot-count by -1
           until dot-count < 2
               move point-pair (i) to temp-points
               move point-pair (dot-count) to point-pair (i)
               move temp-points  to point-pair (dot-count)
               compute i = function random * dot-count + 1
           end-perform
           move dot-count-save to dot-count
           .

       select-100-dots.
           perform varying i from 1 by 1
           until i > 100
               compute x = x-point (i)
               compute y = y-point (i)
               move 2 to dot (x y)
           end-perform
           .

       print-dots.
           open output plot-file
           initiate plot
           perform varying y from 1 by 1 until y > 31
               move spaces to plot-work
               perform varying x from 1 by 1 until x > 31
                   if dot (x y) = 2
                       move "o" to plot-item (x)
                   end-if
               end-perform
               generate plot-line
           end-perform
           terminate plot
           close plot-file
           .

       compute-seed.
           unstring function current-date into
               yyyymmdd hh mm ss
           compute seed =
               (function integer-of-date (yyyymmdd) * 86400)
           compute seed = seed
                 + (hh * 3600) + (mm * 60) + ss
           compute seed = function mod (seed 32768)
           .

       end program circle.


NUM_POINTS = 100
MIN_R = 10
MAX_R = 15

random_circle_points = ->
  rand_point = ->
    Math.floor (Math.random() * (MAX_R * 2 + 1) - MAX_R)

  points = {}
  cnt = 0
  while cnt < 100
    x = rand_point()
    y = rand_point()
    continue unless MIN_R * MIN_R <= x*x + y*y <= MAX_R * MAX_R
    points["#{x},#{y}"] = true
    cnt += 1
  points

plot = (points) ->
  range = [-1 * MAX_R .. MAX_R]
  for y in range
    s = ''
    for x in range
      s += if points["#{x},#{y}"] then '*' else ' '
    console.log s

plot random_circle_points()


(flet ((good-p (x y) (<= 100 (+ (* x x) (* y y)) 255)))
  (loop with x with y with cnt = 0
	with scr = (loop repeat 31 collect (loop repeat 31 collect "  "))
	while (< cnt 100)
	do (when (good-p (- (setf x (random 31)) 15)
			 (- (setf y (random 31)) 15))
	     (setf (elt (elt scr y) x) "@ ")
	     (incf cnt))
	finally (mapc #'(lambda (row) (format t "~{~a~^~}~%" row)) scr)))


import std.stdio, std.random, std.math, std.complex;

void main() {
    char[31][31] table = ' ';

    foreach (immutable _; 0 .. 100) {
        int x, y;
        do {
            x = uniform(-15, 16);
            y = uniform(-15, 16);
        } while(abs(12.5 - complex(x, y).abs) > 2.5);
        table[x + 15][y + 15] = '*';
    }

    writefln("%-(%s\n%)", table);
}


unit Main;

interface

uses
  Winapi.Windows, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  end;

var
  Form1: TForm1;
  Points: TArray<TPoint>;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientHeight := 600;
  ClientWidth := 600;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  i: integer;
  p: TPoint;
  index: integer;
begin
  SetLength(Points, 404);
  i := 0;
  for var y := -15 to 15 do
    for var x := -15 to 15 do
    begin
      if i >= 404 then
        Break;
      var c := Sqrt(x * x + y * y);
      if (10 <= c) and (c <= 15) then
      begin
        inc(i);
        points[i] := TPoint.Create(x, y);
      end;
    end;
  var bm := TBitmap.create;
  bm.SetSize(600, 600);
  with bm.Canvas do
  begin
    Pen.Color := clRed;
    Brush.Color := clRed;
    Brush.Style := bsSolid;
    Randomize;

    for var count := 0 to 99 do
    begin
      repeat
        index := Random(404);
        p := points[index];
      until (not p.IsZero);
      points[index] := TPoint.Zero;

      var cx := 290 + 19 * p.X;
      var cy := 290 + 19 * p.Y;
      Ellipse(cx - 5, cy - 5, cx + 5, cy + 5);
    end;
  end;
  Canvas.Draw(0, 0, bm);
  bm.Free;
end;
end.


(lib 'math)
(lib 'plot)

(define (points (n 100) (radius 10) (rmin 10) (rmax 15)   (x) (y))
	(plot-clear)
	(plot-x-minmax (- rmax))
	(plot-y-minmax( - rmax))

	(for [(i n)]
	(set! x (round (* (random -1) rmax)))
	(set! y (round (* (random -1) rmax)))
	#:when (in-interval? (pythagore x y) rmin rmax)
	;; add a little bit of randomness : dots color and radius
	(plot-fill-color   (hsv->rgb (random) 0.9 0.9))
	(plot-circle x y (random radius)))
	(plot-edit))


defmodule Random do
  defp generate_point(0, _, _, set), do: set
  defp generate_point(n, f, condition, set) do
    point = {x,y} = {f.(), f.()}
    if x*x + y*y in condition and not point in set,
      do:   generate_point(n-1, f, condition, MapSet.put(set, point)),
      else: generate_point(n,   f, condition, set)
  end

  def circle do
    f = fn -> :rand.uniform(31) - 16 end
    points = generate_point(100, f, 10*10..15*15, MapSet.new)
    range = -15..15
    for x <- range do
      for y <- range do
        IO.write if {x,y} in points, do: "x", else: " "
      end
      IO.puts ""
    end
  end
end

Random.circle


include std/console.e

sequence validpoints = {}
sequence discardedpoints = {}
sequence rand100points = {}
atom coordresult
integer randindex

--scan for all possible values. store discarded ones in another sequence, for extra reference.
for y = -15 to 15 do
    for x = -15 to 15 do

        coordresult = sqrt( x * x + y * y )

        if coordresult >= 10 and coordresult <= 15 then --if it would fall in the ring area
            validpoints &= {{x, y, coordresult}} --concatenate (add to the end) the coordinate pair x, y and the
            -- result into a subsequence of sequence validpoints
            else
                discardedpoints &= {{x, y, coordresult}} --else put it in the discarded sequence
        end if

    end for
end for

for i = 1 to 100 label "oneofhundred" do --make 100 random coordinate pairs
    randindex = rand(length(validpoints) ) --random value from 1 to the number of 3 value subsequences in validpoints (the data)

    if length(rand100points) = 0 then --if rand100points sequence is empty, add the first subsequence to it.
        rand100points &= {validpoints[randindex]}

        else --if it isn't empty, then..
            for j = 1 to length(rand100points) do --loop through each "data chunk" in rand100points

                if equal(validpoints[randindex], rand100points[j]) = 1 then --if any are the same as the randomly chosen chunk in
                    retry "oneofhundred" -- validpoints, then retry from one line below the "oneofhundred" loop without incrementing i.
                end if --the continue keyword would increment i instead.

            end for

            rand100points &= {validpoints[randindex]} --length of rand100points isnt 0 and no data chunks match ones that the program
            --already picked before, so add this subsequence chunk to rand100points.
    end if

end for

for i = 1 to 32 do --32 lines
    printf(1,"\n")
    for j = 1 to 32 label "xscan" do --32 characters on each line

        for k = 1 to length(rand100points) do --for every subsequence in this
            if rand100points[k][1]+16 = j and rand100points[k][2]+16 = i then --if the x and y coordinates in the picked points
                printf(1, 178) --(adjusted to minimum of 1,1) are at the same place as in the console output grid
                continue "xscan" --print a funny character and continue to the next "xscan"
            end if
        end for

        printf(1, 176) --if no picked points were there, print another funny character to represent a blank space

    end for
end for

printf(1, "\nNumber of valid coordinate pairs %d :", length(validpoints) )
printf(1, "\nNumber of discarded coordinate pairs : %d", length(discardedpoints) )
printf(1, "\nNumber of randomly picked coordinate pairs : %d\n", length(rand100points) )
any_key()


module CirclePoints =
    let main args =
        let rnd = new System.Random()
        let rand size = rnd.Next(size) - size/2
        let size = 30
        let gen n =
            let rec f (x,y) =
                let t = (int (sqrt (float (x*x + y*y)) ))
                if 10 <= t && t <= 15 then (x,y) else f (rand size, rand size)
            f (rand size, rand size)
        let plot = Array.init 100 (fun n -> gen n)
        for row in 0 .. size-1 do
            let chars = Array.create (size+1) ' '
            Array.choose (fun (x,y) -> if y = (row-size/2) then Some(x) else None) plot
            |> Array.iter (fun x -> chars.[x+size/2] <- 'o')
            printfn "%s" (new string(chars))
        0

#if INTERACTIVE
CirclePoints.main fsi.CommandLineArgs
#else
[<EntryPoint>]
let main args = CirclePoints.main args
#endif


USING: io kernel math.matrices math.order math.ranges
math.statistics math.vectors random sequences strings ;

CHAR: X -15 15 [a,b] dup cartesian-product concat
[ sum-of-squares 100 225 between? ] filter 100 sample
[ 15 v+n ] map 31 31 32 <matrix> [ matrix-set-nths ] keep
[ >string print ] each


// Generate points in [min,max]^2 with constraint
function random_point (min, max, constraint)
  [x, y] = [random(min, max), random(min, max)]
  return constraint(x, y) ? [x, y] : random_point(min, max, constraint)
end

// Generate point list
in_circle = { x, y => 10**2 <= x**2 + y**2 and x**2 + y**2 <= 15**2 }
points = [].comp([0:100], {__ => random_point(-15, 15, in_circle)})

// Show points
for i in [-15:16]
  for j in [-15:16]
    >> [i, j] in points ? "x" : " "
  end
  >
end


program Constrained_Points
  implicit none

  integer, parameter :: samples = 100
  integer :: i, j, n, randpoint
  real :: r

  type points
    integer :: x, y
  end type

  type(points) :: set(500), temp

! Create set of valid points
  n = 0
  do i = -15, 15
    do j = -15, 15
      if(sqrt(real(i*i + j*j)) >= 10.0 .and. sqrt(real(i*i + j*j)) <= 15.0) then
        n = n + 1
        set(n)%x = i
        set(n)%y = j
      end if
    end do
  end do

! create 100 random points
! Choose a random number between 1 and n inclusive and swap point at this index with point at index 1
! Choose a random number between 2 and n inclusive and swap point at this index with point at index 2
! Continue in this fashion until 100 points have been selected
  call random_seed
  do i = 1, samples
    call random_number(r)
    randpoint = r * (n + 1 - i) + i
    temp = set(i)
    set(i) = set(randpoint)
    set(randpoint) = temp
  end do

! In order to facilitate printing sort random points into ascending order
! sort x in ascending order
  do i = 2, samples
     j = i - 1
     temp = set(i)
        do while (j>=1 .and. set(j)%x > temp%x)
           set(j+1) = set(j)
           j = j - 1
        end do
     set(j+1) = temp
  end do

! sort y in ascending order for same x
  do i = 2, samples
     j = i - 1
     temp = set(i)
        do while (j>=1 .and. set(j)%x == temp%x .and. set(j)%y > temp%y)
           set(j+1) = set(j)
           j = j - 1
        end do
     set(j+1) = temp
  end do

! print circle
  write(*,"(a,a)", advance="no") repeat(" ", set(1)%y+15), "*"
  do i = 2, samples
    if(set(i)%x == set(i-1)%x) then
      write(*,"(a,a)", advance="no") repeat(" ", set(i)%y - set(i-1)%y-1), "*"
    else
      n = set(i)%x - set(i-1)%x
      do j = 1, n
        write(*,*)
      end do
      write(*,"(a,a)", advance="no") repeat(" ", set(i)%y+15), "*"
    end if
  end do

end program


g = new graphics

count = 0
do
{
   x = random[-15,15]
   y = random[-15,15]
   r = sqrt[x^2 + y^2]
   if 10 <= r and r <= 15
   {
       count = count + 1
       g.fillEllipseCenter[x,y,.3, .3]
   }
}  while count < 100

g.show[]


## Ring of random points 2/18/17 aev
reset
fn="RingRandPntsGnu";
ttl="Ring of random points"
ofn=fn.".png"; lim=1000;
randgp(top) = floor(rand(0)*top)
set terminal png font arial 12 size 640,640
set output ofn
set title ttl font "Arial:Bold,12"
unset key;
set size square
set parametric
set xrange [-20:20]; set yrange [-20:20];
set style line 1 lt rgb "red"
$rring << EOD
EOD
set print $rring append
do for [i=1:lim] {
  x=randgp(30); y=randgp(30);
  r=sqrt(x**2+y**2);
  if (r>=10&&r<=15) \
    {print x," ",y; print -x," ",-y;print x," ",-y; print -x," ",y;}
}
plot [0:2*pi] sin(t)*10,cos(t)*10, sin(t)*15,cos(t)*15 ls 1,\
$rring using 1:2 with points  pt 7 ps 0.5 lc "black"
set output
unset print


package main

import (
    "bytes"
    "fmt"
    "math/rand"
    "time"
)

const (
    nPts = 100
    rMin = 10
    rMax = 15
)

func main() {
    rand.Seed(time.Now().Unix())
    span := rMax + 1 + rMax
    rows := make([][]byte, span)
    for r := range rows {
        rows[r] = bytes.Repeat([]byte{' '}, span*2)
    }
    u := 0 // count unique points
    min2 := rMin * rMin
    max2 := rMax * rMax
    for n := 0; n < nPts; {
        x := rand.Intn(span) - rMax
        y := rand.Intn(span) - rMax
        // x, y is the generated coordinate pair
        rs := x*x + y*y
        if rs < min2 || rs > max2 {
            continue
        }
        n++ // count pair as meeting condition
        r := y + rMax
        c := (x + rMax) * 2
        if rows[r][c] == ' ' {
            rows[r][c] = '*'
            u++
        }
    }
    for _, row := range rows {
        fmt.Println(string(row))
    }
    fmt.Println(u, "unique points")
}


import Data.List
import Control.Monad
import Control.Arrow
import Rosetta.Knuthshuffle

task = do
  let blanco = replicate (31*31) "  "
      cs = sequence [[-15,-14..15],[-15,-14..15]] :: [[Int]]
      constraint = uncurry(&&).((<= 15*15) &&& (10*10 <=)). sum. map (join (*))
-- select and randomize all circle points
  pts <- knuthShuffle $ filter constraint cs
-- 'paint' first 100 randomized circle points on canvas
  let canvas = foldl (\cs [x,y] -> replaceAt (31*(x+15)+y+15) "/ " cs ) blanco (take 100 pts)
-- show canvas
  mapM_ (putStrLn.concat). takeWhile(not.null). unfoldr (Just . splitAt 31) $ canvas


(import
  math [sqrt]
  random [choice]
  matplotlib.pyplot :as plt)

(setv possible-points
  (lfor
    x (range -15 16)
    y (range -15 16)
    :if (<= 10 (sqrt (+ (** x 2) (** y 2))) 15)
	  [x y]))

(setv [xs ys] (zip #* (map (fn [_] (choice possible-points)) (range 100))))
  ; We can't use random.sample because that samples without replacement.
  ; #* is also known as unpack-iterable
(plt.plot xs ys "bo")
(plt.show)


link graphics

procedure main(A)  # points, inside r, outside r in pixels - default to task values

if \A[1] == "help" then stop("Usage: plot #points inside-radius outside-radius")
points  := \A[1] | 100
outside := \A[2] | 15
inside  := \A[3] | 10
if inside > outside then inside :=: outside

wsize   := integer(2.2*outside)
wsize  <:= 150
center  := wsize/2

WOpen("size="||wsize||","||wsize,"bg=black","fg=white") | stop("Unable to open window")

until(points -:= 1) <= 0 do {
   x := ?(2*outside)-outside   # random x
   y := ?(2*outside)-outside   # and y
   if (inside <= integer(sqrt(x^2+y^2)) ) <= outside then
      DrawPoint(x + center,y + center)
   }
WDone()

end


import java.util.Random;

public class FuzzyCircle {
	static final Random rnd = new Random();
	public static void main(String[] args){
		char[][] field = new char[31][31];
		for(int i = 0; i < field.length; i++){
			for(int j = 0; j < field[i].length; j++){
				field[i][j] = ' ';
			}
		}
		int pointsInDisc = 0;
		while(pointsInDisc < 100){
			int x = rnd.nextInt(31) - 15;
			int y = rnd.nextInt(31) - 15;
			double dist = Math.hypot(x, y);
			if(dist >= 10 && dist <= 15 && field[x + 15][y + 15] == ' '){
				field[x + 15][y + 15] = 'X';
				pointsInDisc++;
			}
		}
		for(char[] row:field){
			for(char space:row){
				System.out.print(space);
			}
			System.out.println();
		}
	}
}


<title>Circle</title>

<canvas id="cv" width="320" height="320"></canvas>


function printcircle(lo::Integer, hi::Integer, ndots::Integer; pad::Integer = 2)
    canvas = falses(2hi + 1, 2hi + 1)
    i = 0
    while i < ndots
        x, y = rand(-hi:hi, 2)
        if lo ^ 2 - 1 < x ^ 2 + y ^ 2 < hi ^ 2 + 1
            canvas[x + hi + 1, y + hi + 1] = true
            i += 1
        end
    end
    # print
    for i in 1:(2hi + 1)
        row = map(j -> j ? "\u25cf " : "  ", canvas[i, :])
        println(" " ^ pad, join(row))
    end
    return canvas
end

printcircle(10, 15, 100)


// version 1.1.3

fun main(args: Array<String>) {
    val r = java.util.Random()
    val points = Array(31) { CharArray(31) { ' ' } }
    var count = 0
    while (count < 100) {
        val x = r.nextInt(31) - 15
        val y = r.nextInt(31) - 15
        val h = x * x + y * y
        if (h in 100..225) {
            points[x + 15][y + 15] = 'o'
            count++
        }
    }
    for (i in 0..30) println(points[i].joinToString(""))
}


{def circ
 {lambda {:cx :cy :r}
  {div {@ style="position:absolute;
                 top: {- :cy :r}px; left: {- :cx :r}px;
                 width: {* 2 :r}px; height: {* 2 :r}px;
                 border: 1px solid #000; border-radius: :rpx;"}} }}
-> circ

{def fuzzy_circle
 {lambda {:cx :cy :rmin :rmax :n}
  {circ :cx :cy :rmax}
  {circ :cx :cy :rmin}
  {S.map {{lambda {:cx :cy :rmin :rmax :i}
                {let { {:cx :cx} {:cy :cy}
                       {:rmin :rmin} {:rmax :rmax}
                       {:x {- {round {* {random} {* 2 :rmax}}} :rmax}}
                       {:y {- {round {* {random} {* 2 :rmax}}} :rmax}}
                     } {let { {:x {+ :cx :x }}
                              {:y {+ :cy :y }}
                              {:rr {+ {* :x :x} {* :y :y}}}
                              {:r2min {* :rmin :rmin}}
                              {:r2max {* :rmax :rmax}}
                    } {if {or {< :rr :r2min} {> :rr :r2max}}
                       then else {circ :x :y 2}}
           }}} :cx :cy :rmin :rmax}
          {S.serie 1 :n}} }}
-> fuzzy_circle

{fuzzy_circle 200 700 80 120 1000}
-> plots 1000 dots between the circles r=80 and r=120 centered at [200,700]
   directly in the wiki page (out of any canvas or svg contexts) as it
   can be seen in http://lambdaway.free.fr/lambdawalks/?view=fuzzy_circle


'   RC Constrained Random Points on a Circle

nomainwin

WindowWidth  =400
WindowHeight =430

open "Constrained Random Points on a Circle" for graphics_nsb as #w

#w "trapclose [quit]"
#w "down ; size 7 ; color red ; fill black"

for i =1 to 1000
  do
     x =int( 30 *rnd( 1)) -15
     y =int( 30 *rnd( 1)) -15
  loop until IsInRange( x, y) =1
  #w "set "; 200 +10 *x; " "; 200 - 10 *y
next

wait

function IsInRange( x, y)
  z =sqr( x*x +y*y)
  if 10 <=z and z <=15 then IsInRange =1 else IsInRange =0
end function

[quit]
close #w
end


10 MODE 1:RANDOMIZE TIME
20 FOR J=1 TO 100
30 X=INT(RND*30-15)
40 Y=INT(RND*30-15)
50 D=X*X+Y*Y
60 IF D<100 OR D>225 THEN GOTO 40
70 PLOT 320+10*X,200+10*Y:LOCATE 1,1:PRINT J
80 NEXT
90 CALL &BB06 ' wait for key press


t, n = {}, 0
for y=1,31 do t[y]={} for x=1,31 do t[y][x]="  " end end
repeat
  x, y = math.random(-15,15), math.random(-15,15)
  rsq = x*x + y*y
  if rsq>=100 and rsq<=225 and t[y+16][x+16]=="  " then
    t[y+16][x+16], n = "██", n+1
  end
until n==100
for y=1,31 do print(table.concat(t[y])) end


 a := table():
 i := 1:
 while i < 100 do
 ba := (rand(-15 .. 15))():
 bb := (rand(-15 .. 15))():
 b := evalf(sqrt(ba^2+bb^2)):
 if b <= 15 and b >= 10
  then a[i] := [ba, bb]:
  i := i+1:
 end if:
 end do:
 plots:-pointplot(convert(a,list));


function [xCoordinates,yCoordinates] = randomDisc(numPoints)

    xCoordinates = [];
    yCoordinates = [];

    %Helper function that samples a random integer from the uniform
    %distribution between -15 and 15.
    function nums = randInt(n)
        nums = round((31*rand(n,1))-15.5);
    end

    n = numPoints;

    while n > 0

        x = randInt(n);
        y = randInt(n);

        norms = sqrt((x.^2) + (y.^2));
        inBounds = find((10 <= norms) & (norms <= 15));

        xCoordinates = [xCoordinates; x(inBounds)];
        yCoordinates = [yCoordinates; y(inBounds)];

        n = numPoints - numel(xCoordinates);
    end

    xCoordinates(numPoints+1:end) = [];
    yCoordinates(numPoints+1:end) = [];

end


randomDisc(numPoints):= block([p: []],
  local(goodp, random_int),
  goodp(x, y):=block([r: sqrt(x^2+y^2)],
    r>=10 and r<=15
    ),
  random_int():= block([m: 15], m - random(2*(m+1)-1)),
  while length(p)<numPoints do block (
    [x: random_int(), y : random_int()],
    if goodp(x, y) then (
      p: cons([x, y], p)
      )
    ),
  p)$

p: randomDisc(100)$
plot2d(['discrete, p], ['style, 'points]);


import tables, math, complex, random

type Point = tuple[x, y: int]

var world = initCountTable[Point]()
var possiblePoints = newSeq[Point]()

for x in -15..15:
  for y in -15..15:
    if abs(complex(x.float, y.float)) in 10.0..15.0:
      possiblePoints.add((x,y))

randomize()
for i in 0..100: world.inc possiblePoints.sample

for x in -15..15:
  for y in -15..15:
    let key = (x, y)
    if key in world and world[key] > 0:
      stdout.write ' ' & $min(9, world[key])
    else:
      stdout.write "  "
  echo ""


let p x y =
  let d = sqrt(x ** 2.0 +. y ** 2.0) in
  10.0 <= d && d <= 15.0

let () =
  Random.self_init();
  let rec aux i acc =
    if i >= 100 then acc else
      let x = (Random.float 40.0) -. 20.0
      and y = (Random.float 40.0) -. 20.0 in
      if (p x y)
      then aux (succ i) ((x,y)::acc)
      else aux i acc
  in
  let points = aux 0 [] in
  let g = Array.init 40 (fun _ -> String.make 40 ' ') in
  List.iter (fun (x,y) ->
    let x = (int_of_float x) + 20
    and y = (int_of_float y) + 20 in
    g.(y).[x] <- 'o'
  ) points;
  Array.iter print_endline g


my @points;
while (@points < 100) {
        my ($x, $y) = (int(rand(31))-15, int(rand(31)) - 15);
        my $r2 = $x*$x + $y*$y;
        next if $r2 < 100 || $r2 > 225;
        push @points, [$x, $y];
}

print << 'HEAD';
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox 0 0 400 400
200 200 translate 10 10 scale
0 setlinewidth
1 0 0 setrgbcolor
0 0 10 0 360 arc stroke
0 0 15 360 0 arcn stroke
0 setgray
/pt { .1 0 360 arc fill } def
HEAD

print "@$_ pt\n" for @points;
print "%%EOF";


with javascript_semantics
sequence screen = repeat(repeat(' ',31),31)
integer x, y, count = 0
atom r
while 1 do
    x = rand(31)
    y = rand(31)
    r = sqrt(power(x-16,2)+power(y-16,2))
    if r>=10 and r<=15 then
        screen[x][y] = 'x'
        count += 1
        if count>=100 then exit end if
    end if
end while
puts(1,join(screen,"\n"))


constrain: procedure options (main);
   declare 1 point (100),
            2 x fixed binary,
            2 y fixed binary;
   declare (i, j, a, b, c) fixed binary;

   j = 0;
   do i = 1 to 100;
      a = 30*random()-15; b = 30*random()-15;
      c = sqrt(a**2 + b**2);
      if abs(c) >= 10 & abs(c) <= 15 then
         do; j = j + 1; x(j) = a; y(j) = b; end;
   end;

   /* PLOT */
   declare table(-15:15, -15:15) character (1);
   table = ' ';
   do i = 1 to j;
      table(x(i), y(i)) = '*';
   end;
   do i = -15 to 15;
      put skip;
      do j = -15 to 15;
         put edit (table(i,j)) (a);
      end;
   end;
end constrain;


$MinR2 = 10 * 10
$MaxR2 = 15 * 15

$Points = @{}

While ( $Points.Count -lt 100 )
    {
    $X = Get-Random -Minimum -16 -Maximum 17
    $Y = Get-Random -Minimum -16 -Maximum 17
    $R2 = $X * $X + $Y * $Y

    If ( $R2 -ge $MinR2 -and $R2 -le $MaxR2 -and "$X,$Y" -notin $Points.Keys )
        {
        $Points += @{ "$X,$Y" = 1 }
        }
    }

ForEach ( $Y in -16..16 ) { ( -16..16 | ForEach { ( " ", "*" )[[int]$Points["$_,$Y"]] } ) -join '' }


:- use_module(library(clpfd)).

circle :-
	bagof([X,Y], init(X,Y), BL),
	length(BL, N),
	length(L, 100),
	maplist(choose(BL, N), L),
	draw_circle(L).

% point selection
choose(BL, N, V) :-
	I is random(N),
	nth0(I, BL, V).

% to find all couples of numbers verifying
% 100 <= x^2 + y^2 <= 225
init(X1, Y1) :-
	X in -15..15,
	Y in -15..15,
	X*X + Y*Y #>= 100,
	X*X + Y*Y #=< 225,
	label([X,Y]),
	X1 is 10 * X + 200,
	Y1 is 10 * Y + 200.

draw_circle(L) :-
	new(D, window('Circle')),
	send(D, size,size(400,400)),
	forall(member([X,Y], L),
	       (   new(C, circle(4)),
		   send(C, fill_pattern, colour(@default, 0, 0, 0)),
		   send(C, center(point(X,Y))),
		   send(D, display, C))),
	send(D, open).


CreateImage(0,31,31)
StartDrawing(ImageOutput(0))
  For i=1 To 100
    Repeat
      x=Random(30)-15
      y=Random(30)-15
      R.f=Sqr(x*x+y*y)
    Until 10<=R And R<=15
    Plot(x+15,y+15,#Red)
  Next
StopDrawing()

Title$="PureBasic Plot"
Flags=#PB_Window_SystemMenu
OpenWindow(0,#PB_Ignore,#PB_Ignore,ImageWidth(0),ImageHeight(0),Title$,Flags)
ImageGadget(0,0,0,ImageWidth(0),ImageHeight(0),ImageID(0))
Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow


>>> from collections import defaultdict
>>> from random import choice
>>> world = defaultdict(int)
>>> possiblepoints = [(x,y) for x in range(-15,16)
		  for y in range(-15,16)
		  if 10 <= abs(x+y*1j) <= 15]
>>> for i in range(100): world[choice(possiblepoints)] += 1

>>> for x in range(-15,16):
	print(''.join(str(min([9, world[(x,y)]])) if world[(x,y)] else ' '
			  for y in range(-15,16)))

             1     1
          1 1
      11 1     1  1     1
     111  1     1211
      1   2    1 1    11
      1  11         21
     1   1            11  1
   1  2                1 1

 1  2
   1 1                      1
   1 1
   2                      11
  1                         1
                         1

  1                          1
                         1
                         2
                            1
     1                  1 1
      1                2   1
   1   3            11  2
    11   1    1      1   2
            1   1    2
        1  1
         1      1     1
          2 2   1
               1


RMin <- 10
RMax <- 15
NPts <- 100

# instead of a for loop, we generate what should be enough points
# also take care to have enough range to avoid rounding inaccuracies
nBlock <- NPts * ((RMax/RMin) ^ 2)
nValid <- 0
while (nValid < NPts) {
	X <- round(runif(nBlock, -RMax - 1, RMax + 1))
	Y <- round(runif(nBlock, -RMax - 1, RMax + 1))
	R <-  sqrt(X^2 + Y^2)
	Valid <- ( (R >= RMin) & (R <= RMax) )
	nValid <- sum(Valid)
	nBlock <- 2 * nBlock
}
plot(X[Valid][1:NPts],Y[Valid][1:NPts], pch=19, cex=0.25, col="blue",
	xlab="x",ylab="y",main="Fuzzy circle", xlim=c(-RMax,RMax), ylim=c(-RMax,RMax) )


#lang racket

(require plot plot/utils)

(plot (points (for*/lists (result)
                ([_ (in-naturals)]
                 #:break (= 100 (length result))
                 [xy (in-value (v- (vector (random 31) (random 31))
                                   #(15 15)))]
                 #:when (<= 10 (vmag xy) 15))
                xy)))


my @range = -15..16;

my @points = gather for @range X @range -> ($x, $y) {
    take [$x,$y] if 10 <= sqrt($x*$x+$y*$y) <= 15
}
my @samples = @points.roll(100); # or .pick(100) to get distinct points

# format and print
my %matrix;
for @range X @range -> ($x, $y) { %matrix{$y}{$x} = ' ' }
%matrix{.[1]}{.[0]} = '*' for @samples;
%matrix{$_}{@range}.join(' ').say for @range;


/*REXX program  generates  100  random points  in an  annulus:   10  ≤  √(x²≤y²)  ≤  15 */
parse arg pts LO HI .                            /*obtain optional args from the C.L.   */
if pts==''  then pts= 100                        /*Not specified?  Then use the default.*/
if  LO==''  then  LO= 10;            LO2= LO**2  /*define a shortcut for squaring   LO. */
if  HI==''  then  HI= 15;            HI2= HI**2  /*   "   "    "      "      "      HI. */
$=
       do x=-HI;                      xx= x*x    /*generate all possible annulus points.*/
       if x>0  &  xx>HI2  then leave             /*end of annulus points generation ?   */
           do y=-HI;          s= xx + y*y
           if (y<0 & s>HI2) | s<LO2  then iterate
           if  y>0 & s>HI2           then leave
           $= $  x','y                           /*add a point─set to the  $  list.     */
           end   /*y*/
       end       /*x*/
                                         #= words($);   @.=  /*def: plotchr; #pts; lines*/
   do pts;  parse value word($, random(1,#))  with  x ',' y  /*get rand point in annulus*/
   @.y= overlay('☼',  @.y,  x+x + HI+HI + 1)                 /*put a plot char on a line*/
   end   /*pts*/                                 /* [↑]  maintain aspect ratio on X axis*/
                                                 /*stick a fork in it,  we're all done. */
   do y=-HI  to HI;      say @.y;   end          /*display the annulus to the terminal. */


load "guilib.ring"

new qapp
        {
        win1 = new qwidget() {
                   setwindowtitle("drawing using qpainter")
                   setgeometry(100,100,500,500)
                   label1 = new qlabel(win1) {
                            setgeometry(10,10,400,400)
                            settext("")
                  }
                  new qpushbutton(win1) {
                      setgeometry(200,400,100,30)
                      settext("draw")
                      setclickevent("draw()")
                  }
                  show()
         }
         exec()
         }

func draw
        p1 = new qpicture()
             color = new qcolor() {
             setrgb(0,0,255,255)
        }
        pen = new qpen() {
              setcolor(color)
              setwidth(1)
        }
        new qpainter() {
            begin(p1)
            setpen(pen)

        for i = 1 to 1000
            x = random(31)-16
            y = random(31)-16
            r = sqrt (pow(x,2) + pow(y,2))
            if r >= 10 if r <= 15 drawpoint(x*2, y*2) ok ok
        next

        endpaint()
        }
        label1 { setpicture(p1) show() }


points = (1..100).map do
  # choose a random radius and angle
  angle = rand * 2.0 * Math::PI
  rad   = rand * 5.0 + 10.0
  # convert back from polar to cartesian coordinates
  [rad * Math::cos(angle), rad * Math::sin(angle)].map(&:round)
end

(-15..15).each do |row|
  puts (-15..15).map { |col| points.include?([row, col]) ? "X" : " " }.join
end

load 'raster_graphics.rb'

pixmap = Pixmap.new(321,321)
pixmap.draw_circle(Pixel.new(160,160),90,RGBColour::BLACK)
pixmap.draw_circle(Pixel.new(160,160),160,RGBColour::BLACK)
points.each {|(x,y)| pixmap[10*(x+16),10*(y+16)] = RGBColour::BLACK}
pngfile = __FILE__
pngfile[/\.rb/] = ".png"
pixmap.save_as_png(pngfile)


w = 320
h = 320
dim canvas(w,h)
for pts = 1 to 1000
  x = (rnd(1) * 31) - 15
  y = (rnd(1) * 31) - 15
  r = x * x + y * y
  if (r > 100) and (r < 225) then
    x = int(x * 10 + w/2)
    y = int(y * 10 + h/2)
    canvas(x,y) = 1
  end if
next pts

' -----------------------------
' display the graphic
' -----------------------------
graphic #g, w,h
for x = 1 to w
  for y = 1 to h
     if canvas(x,y) = 1 then  #g "color green ; set "; x; " "; y else #g "color blue ; set "; x; " "; y
  next y
next x
render #g
#g "flush"


extern crate rand;

use rand::Rng;

const POINTS_N: usize = 100;

fn generate_point<R: Rng>(rng: &mut R) -> (i32, i32) {
    loop {
        let x = rng.gen_range(-15, 16); // exclusive
        let y = rng.gen_range(-15, 16);

        let r2 = x * x + y * y;
        if r2 >= 100 && r2 <= 225 {
            return (x, y);
        }
    }
}

fn filtering_method<R: Rng>(rng: &mut R) {
    let mut rows = [[" "; 62]; 31];

    // Generate points
    for _ in 0..POINTS_N {
        let (x, y) = generate_point(rng);
        rows[(y + 15) as usize][(x + 15) as usize * 2] = "*";
    }

    // draw the points
    for row in &rows {
        println!("{}", row.concat());
    }
}

fn precalculating_method<R: Rng>(rng: &mut R) {
    // Generate all possible points
    let mut possible_points = Vec::with_capacity(404);
    for y in -15..=15 {
        for x in -15..=15 {
            let r2 = x * x + y * y;
            if r2 >= 100 && r2 <= 225 {
                possible_points.push((x, y));
            }
        }
    }

    // A truncated Fisher-Yates shuffle
    let len = possible_points.len();
    for i in (len - POINTS_N..len).rev() {
        let j = rng.gen_range(0, i + 1);
        possible_points.swap(i, j);
    }

    // turn the selected points into "pixels"
    let mut rows = [[" "; 62]; 31];
    for &(x, y) in &possible_points[len - POINTS_N..] {
        rows[(y + 15) as usize][(x + 15) as usize * 2] = "*";
    }

    // draw the "pixels"
    for row in &rows {
        println!("{}", row.concat());
    }
}

fn main() {
    let mut rng = rand::weak_rng();

    filtering_method(&mut rng);

    precalculating_method(&mut rng);
}


import java.awt.{ Color, geom,Graphics2D ,Rectangle}
import scala.math.hypot
import scala.swing.{MainFrame,Panel,SimpleSwingApplication}
import scala.swing.Swing.pair2Dimension
import scala.util.Random

object CirculairConstrainedRandomPoints extends SimpleSwingApplication {
  //min/max of display-x resp. y
  val dx0, dy0 = 30; val dxm, dym = 430
  val prefSizeX, prefSizeY = 480

  val palet = Map("b" -> Color.blue, "g" -> Color.green, "r" -> Color.red, "s" -> Color.black)
  val cs = List((0, 0, 10, "b"), (0, 0, 15, "g")) //circle position and color
  val xmax, ymax = 20; val xmin, ymin = -xmax

  class Coord(x: Double, y: Double) {
    def dx = (((dxm - dx0) / 2 + x.toDouble / xmax * (dxm - dx0) / 2) + dx0).toInt
    def dy = (((dym - dy0) / 2 - y.toDouble / ymax * (dym - dy0) / 2) + dy0).toInt
  }

  object Coord {
    def apply(x: Double, y: Double) = new Coord(x, y)
  }

  //points:
  val points =
    new Iterator[Int] { val r = new Random;def next = r.nextInt(31) - 15; def hasNext = true }.toStream.
      zip(new Iterator[Int] { val r = new Random; def next = r.nextInt(31) - 15; def hasNext = true }.toStream).
      map { case (x, y) => (x, y, hypot(x, y)) }.filter { case (x, y, r) => r >= 10 && r <= 15 }.take(100).toSeq.
      map { case (x, y, r) => new Rectangle(Coord(x, y).dx - 2, Coord(x, y).dy - 2, 4, 4) }

  private def ui = new Panel {
    background = Color.white
    preferredSize = (prefSizeX, prefSizeY)

    class Circle(center: Coord, r: Double, val color: Color) {
      val dr = (Coord(r, 0).dx - pcentre.dx) * 2
      val dx = center.dx - dr / 2
      val dy = center.dy - dr / 2
    }

    object Circle {
      def apply(x: Double, y: Double, r: Double, color: Color) =
        new Circle(Coord(x, y), r, color)
    }

    val pcentre = Coord(0, 0)
    val pxmax = Coord(xmax, 0); val pxmin = Coord(xmin, 0)
    val pymax = Coord(0, ymax); val pymin = Coord(0, ymin)

    //axes:
    val a_path = new geom.GeneralPath
    a_path.moveTo(pxmin.dx, pxmin.dy); a_path.lineTo(pxmax.dx, pxmax.dy) //x-axis
    a_path.moveTo(pymin.dx, pymin.dy); a_path.lineTo(pymax.dx, pymax.dy) //y-axis

    //labeling:
    val labels = List(-20, -15, -10, -5, 5, 10, 15, 20)
    labels.foreach { x => { val p = Coord(x, 0); a_path.moveTo(p.dx, p.dy - 3); a_path.lineTo(p.dx, p.dy + 3) } }
    labels.foreach { y => { val p = Coord(0, y); a_path.moveTo(p.dx - 3, p.dy); a_path.lineTo(p.dx + 3, p.dy) } }
    val xlabels = labels.map(x => { val p = Coord(x, 0); Triple(x.toString, p.dx - 3, p.dy + 20) })
    val ylabels = labels.map(y => { val p = Coord(0, y); Triple(y.toString, p.dx - 20, p.dy + 5) })

    //circles:
    val circles = cs.map { case (x, y, r, c) => Circle(x, y, r, palet(c)) }

    override def paintComponent(g: Graphics2D) = {
      super.paintComponent(g)
      circles.foreach { c => { g.setColor(c.color); g.drawOval(c.dx, c.dy, c.dr, c.dr) } }
      g.setColor(palet("r")); points.foreach(g.draw(_))
      g.setColor(palet("s")); g.draw(a_path)
      xlabels.foreach { case (text, px, py) => g.drawString(text, px, py) }
      ylabels.foreach { case (text, px, py) => g.drawString(text, px, py) }
    }
  } // def ui

  def top = new MainFrame {
    title = "Rosetta Code >>> Task: Constrained random points on a circle | Language: Scala"
    contents = ui
  }
}


var points = [];
while (points.len < 100) {
    var (x, y) = 2.of{31.rand.int - 15}...;
    var r2 = (x**2 + y**2);
    if ((r2 >= 100) && (r2 <= 225)) {
        points.append([x, y]);
    }
}

print <<'HEAD';
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox 0 0 400 400
200 200 translate 10 10 scale
0 setlinewidth
1 0 0 setrgbcolor
0 0 10 0 360 arc stroke
0 0 15 360 0 arcn stroke
0 setgray
/pt { .1 0 360 arc fill } def
HEAD

points.each { |pt| say "#{pt.join(' ')} pt" };
print '%%EOF';


open XWindows ;
open Motif ;

val plotWindow = fn coords =>                                                               (*  input list of int*int  within 'dim' *)
let
  val dim    =  {tw=325,th=325} ;
  val shell  =  XtAppInitialise      ""    "demo" "top" [] [ XmNwidth (#tw dim), XmNheight (#th dim) ] ;        (* single call only *)
  val main   =  XmCreateMainWindow   shell    "main"       [ XmNmappedWhenManaged true ]   ;
  val canvas =  XmCreateDrawingArea  main   "drawarea"     [ XmNwidth (#tw dim), XmNheight (#th dim) ] ;
  val usegc  =  DefaultGC (XtDisplay canvas) ;
  val put    =  fn (w,s,t)=> (
                    XSetForeground usegc 0xfffffff ;
                    XFillRectangle (XtWindow canvas) usegc (Area{x=0,y=0,w = #tw dim, h= #th dim})  ;
		    XSetForeground usegc 0  ;
                    XDrawPoints  (XtWindow canvas) usegc (  List.map  (fn (x,y)=>XPoint {x=x,y=y}) coords )  CoordModeOrigin ;
		    t )
in

  (
   XtSetCallbacks   canvas [ (XmNexposeCallback , put) ] XmNarmCallback ;
   XtManageChild    canvas ;
   XtManageChild    main ;
   XtRealizeWidget  shell
  )

end;

val urandomlist =  fn seed => fn n =>
(* put code from (www.rosettacode.org) wiki/Random_numbers#Standard_ML 'urandomlist' here
input : seed and number of drawings *)
end;

val normalizedPts = fn () =>                                                  (* select ([0,1]*[0,1]) points in normalized bandwidth *)
 let
   val realseeds  =  ( 972.1 , 10009.3 ) ;
   val usum       =  fn  (u,v)     => u*(u-1.0) + v*(v-1.0) ;
   val lim        =  ( ~350.0/900.0, ~225.0/900.0 ) ;                                                              (* limits to usum  *)
   val select     =  fn i =>  usum i <= #2 lim  andalso  usum i >= #1 lim  ;                      (* select according to inequalities *)
   val uv         =  ListPair.zip ( urandomlist (#1 realseeds) 2500 , urandomlist (#2 realseeds) 2500 )          (* take 2500 couples *)
 in
   List.take ( List.filter select uv , 1000 )
end ;


let nPoints = 100

func generatePoint() -> (Int, Int) {
  while true {
    let x = Int.random(in: -15...16)
    let y = Int.random(in: -15...16)
    let r2 = x * x + y * y

    if r2 >= 100 && r2 <= 225 {
      return (x, y)
    }
  }
}

func filteringMethod() {
  var rows = [[String]](repeating: Array(repeating: " ", count: 62), count: 31)

  for _ in 0..<nPoints {
    let (x, y) = generatePoint()

    rows[y + 15][x + 15 * 2] = "*"
  }

  for row in rows {
    print(row.joined())
  }
}

func precalculatingMethod() {
  var possiblePoints = [(Int, Int)]()

  for y in -15...15 {
    for x in -15...15 {
      let r2 = x * x + y * y

      if r2 >= 100 && r2 <= 225 {
        possiblePoints.append((x, y))
      }
    }
  }

  possiblePoints.shuffle()

  var rows = [[String]](repeating: Array(repeating: " ", count: 62), count: 31)

  for (x, y) in possiblePoints {
    rows[y + 15][x + 15 * 2] = "*"
  }

  for row in rows {
    print(row.joined())
  }
}

print("Filtering method:")
filteringMethod()

print("Precalculating method:")
precalculatingMethod()


program main;

  bit [39:0] bitmap [40];

  class Point;
    rand bit signed [4:0] x;
    rand bit signed [4:0] y;

    constraint on_circle_edge {
      (10*10) <= (x*x + y*y);
      (x*x + y*y) <= (15*15);
    };

    function void do_point();
      randomize;
      bitmap[x+20][y+20] = 1;
    endfunction
  endclass

  initial begin
    Point p = new;
    repeat (100) p.do_point;
    foreach (bitmap[row]) $display( "%b", bitmap[row]);
  end

endprogram


package require Tcl 8.5

# Generate random point at specified distance from the centre
proc getPoint {range from to} {
    set r2 [expr {$range / 2}]
    set f2 [expr {$from ** 2}]
    set t2 [expr {$to ** 2}]
    while 1 {
	set x [expr {int($range * rand())}]
	set y [expr {int($range * rand())}]
	set d2 [expr {($x-$r2)**2 + ($y-$r2)**2}]
	if {$d2 >= $f2 && $d2 <= $t2} {
	    return [list $y $x]
	}
    }
}

# Make somewhere to store the counters
set ary [lrepeat 31 [lrepeat 31 0]]

# Generate 100 random points
for {set i 0} {$i < 100} {incr i} {
    set location [getPoint 31 10 15]
    # Increment the counter for the point
    lset ary $location [expr {1 + [lindex $ary $location]}]
}

# Simple renderer
foreach line $ary {
    foreach c $line {
	puts -nonewline [expr {$c == 0 ? " " : $c > 9 ? "X" : $c}]
    }
    puts ""
}


import "graphics" for Canvas, Color
import "dome" for Window
import "random" for Random

class Game {
    static init() {
        Window.title = "Constrained random points on a circle"
        var width = 800
        var height = 800
        Window.resize(width, height)
        Canvas.resize(width, height)
        var rand = Random.new()
        var count = 0
        var max = 100 // set to 1000 to produce a much more pronounced annulus
        while (true) {
            var x = rand.int(-15, 16)
            var y = rand.int(-15, 16)
            var dist = (x*x + y*y).sqrt
            if (10 <= dist && dist <= 15) {
                // translate coordinates to fit in the window
                Canvas.circlefill((x + 16) * 25, (y + 16) * 25, 2, Color.white)
                count = count + 1
                if (count == max) break
            }
        }
    }

    static update() {}

    static draw(alpha) {}
}


include c:\cxpl\codes;  \intrinsic 'code' declarations
int X, Y, C, R2;
[SetVid($13);           \set 320x200x8 graphics mode
C:= 0;                  \initialize point counter
repeat  X:= Ran(31)-15; \range -15..+15
        Y:= Ran(31)-15;
        R2:= X*X + Y*Y;
        if R2>=10*10 & R2<=15*15 then
                [Point(X+160, Y+100, $F);  C:= C+1];
until C >= 100;
C:= ChIn(1);            \wait for keystroke
SetVid(3);              \restore normal text mode
]


xy:=(0).walker(*).tweak(fcn{  // generate infinite random pairs (lazy)
   x:=(-15).random(16); y:=(-15).random(16);
   if(not (100<=(x*x + y*y)<=225)) Void.Skip else T(x,y)
});

const N=31;  // [-15..15] includes 0
array:=(" ,"*N*N).split(",").copy();  // bunch of spaces (list)

xy.walk(100).apply2(fcn([(x,y)],array){array[x+15 + N*(y+15)]="*"},array);
foreach n in ([0..30]){ array[n*N,30].concat().println(); }


F orientation(p, q, r)
   V val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y)
   I val == 0
      R 0
   R I val > 0 {1} E 2

F calculateConvexHull(points)
   [(Int, Int)] result

   I points.len < 3
      R points

   V indexMinX = 0
   L(p) points
      V i = L.index
      I p.x < points[indexMinX].x
         indexMinX = i

   V p = indexMinX
   V q = 0

   L
      result.append(points[p])

      q = (p + 1) % points.len

      L(i) 0 .< points.len
         I orientation(points[p], points[i], points[q]) == 2
            q = i

      p = q
      I p == indexMinX
         L.break

   R result

V points = [(16, 3),
            (12, 17),
            (0, 6),
            (-4, -6),
            (16, 6),
            (16, -7),
            (17, -4),
            (5, 19),
            (19, -8),
            (3, 16),
            (12, 13),
            (3, -4),
            (17, 5),
            (-3, 15),
            (-3, -9),
            (0, 11),
            (-9, -3),
            (-4, -2),
            (12, 10)]

V hull = calculateConvexHull(points)
L(i) hull
   print(i)


DEFINE POINTSIZE="4"
TYPE PointI=[INT x,y]

CARD FUNC GetAddr(INT ARRAY points BYTE index)
RETURN (points+POINTSIZE*index)

BYTE FUNC GetMinXIndex(INT ARRAY points BYTE pLen)
  PointI POINTER p
  BYTE i,index
  INT minX

  p=GetAddr(points,0)
  minX=p.x
  index=0
  FOR i=1 TO pLen-1
  DO
    p=GetAddr(points,i)
    IF p.x<minX THEN
      minX=p.x
      index=i
    FI
  OD
RETURN (index)

BYTE FUNC Orientation(PointI POINTER p,q,r)
  INT v
  v=(q.y-p.y)*(r.x-q.x)
  v==-(q.x-p.x)*(r.y-q.y)

  IF v=0 THEN
    RETURN (0)
  ELSEIF v>0 THEN
    RETURN (1)
  FI
RETURN (2)

PROC ConvexHull(INT ARRAY points BYTE pLen
  INT ARRAY res BYTE POINTER resLen)
  PointI POINTER pSrc,pDst,p1,p2,p3
  BYTE minIndex,i,p,q

  IF pLen<3 THEN
    resLen^=pLen
    MoveBlock(res,points,pLen*POINTSIZE)
    RETURN
  FI

  resLen^=0
  minIndex=GetMinXIndex(points,pLen)
  p=minIndex q=0
  DO
    pSrc=GetAddr(points,p)
    pDst=GetAddr(res,resLen^)
    pDst.x=pSrc.x
    pDst.y=pSrc.y
    resLen^==+1

    q=(p+1) MOD pLen
    FOR i=0 TO pLen-1
    DO
      p1=GetAddr(points,p)
      p2=GetAddr(points,i)
      p3=GetAddr(points,q)
      IF Orientation(p1,p2,p3)=2 THEN
        q=i
      FI
    OD
    p=q
  UNTIL p=minIndex
  OD
RETURN

PROC PrintPoints(INT ARRAY points BYTE len)
  PointI POINTER p
  BYTE i

  FOR i=0 TO len-1
  DO
    p=GetAddr(points,i)
    PrintF("(%I,%I) ",p.x,p.y)
  OD
RETURN

PROC Main()
  INT ARRAY points=[
    16 3 12 17 0 6 65532 65530
    16 6 16 65529 17 65532 5 19
    19 65528 3 16 12 13 3 65532
    17 5 65533 15 65533 65527
    0 11 65527 65533 65532 65534
    12 10]
  INT ARRAY result(38)
  BYTE pLen=[19],rlen

  ConvexHull(points,pLen,result,@rlen)

  PrintE("Points:")
  PrintPoints(points,pLen)
  PutE() PutE()
  PrintE("Convex hull:")
  PrintPoints(result,rLen)
RETURN


with Ada.Text_IO;
with Ada.Containers.Vectors;

procedure Convex_Hull is

   type Point is record
      X, Y : Integer;
   end record;

   package Point_Vectors is
      new Ada.Containers.Vectors (Index_Type   => Positive,
                                  Element_Type => Point);
   use Point_Vectors;

   function Find_Convex_Hull (Vec : in Vector) return Vector is

      function Counter_Clock_Wise (A, B, C : in Point) return Boolean is
         ((B.X - A.X) * (C.Y - A.Y) > (B.Y - A.Y) * (C.X - A.X));

      function Less_Than (Left, Right : Point) return Boolean is
         (Left.X < Right.X);

      package Sorter is
         new Point_Vectors.Generic_Sorting (Less_Than);

      Sorted : Vector := Vec;
      Result : Vector := Empty_vector;
      use type Ada.Containers.Count_Type;
   begin
      if Vec = Empty_Vector then
         return Empty_Vector;
      end if;

      Sorter.Sort (Sorted);

      --  Lower hull
      for Index in Sorted.First_Index .. Sorted.Last_Index loop
         while
           Result.Length >= 2 and then
           not Counter_Clock_Wise (Result (Result.Last_Index - 1),
                                   Result (Result.Last_Index),
                                   Sorted (Index))
         loop
            Result.Delete_Last;
         end loop;
         Result.Append (Sorted (Index));
      end loop;

      --  Upper hull
      declare
         T : constant Ada.Containers.Count_Type := Result.Length + 1;
      begin
         for Index in reverse Sorted.First_Index .. Sorted.Last_Index loop
            while
              Result.Length >= T and then
              not Counter_Clock_Wise (Result (Result.Last_Index - 1),
                                      Result (Result.Last_Index),
                                      Sorted (Index))
            loop
               Result.Delete_Last;
            end loop;
            Result.Append (Sorted (Index));
         end loop;
      end;

      Result.Delete_Last;
      return Result;
   end Find_Convex_Hull;

   procedure Show (Vec : in Vector) is
      use Ada.Text_IO;
   begin
      Put ("[ ");
      for Point of Vec loop
         Put ("(" & Point.X'Image & "," & Point.Y'Image & ")");
      end loop;
      Put (" ]");
   end Show;

   Vec : constant Vector :=
     (16, 3) & (12,17) & ( 0, 6) & (-4,-6) & (16, 6) &
     (16,-7) & (16,-3) & (17,-4) & ( 5,19) & (19,-8) &
     ( 3,16) & (12,13) & ( 3,-4) & (17, 5) & (-3,15) &
     (-3,-9) & ( 0,11) & (-9,-3) & (-4,-2) & (12,10);
begin
   Show (Find_Convex_Hull (Vec));
   Ada.Text_IO.New_Line;
end Convex_Hull;


define :point [x y][]

orientation: function [P Q R][
    val: sub (Q\y - P\y)*(R\x - Q\x) (Q\x - P\x)*(R\y - Q\y)
    if val=0 -> return 0
    if val>0 -> return 1
    return 2
]

calculateConvexHull: function [points][
    result: new []

    if 3 > size points [
        loop points 'p -> 'result ++ p
    ]

    indexMinX: 0
    loop.with:'i points 'p [
        if p\x < get points\[indexMinX] 'x ->
            indexMinX: i
    ]

    p: indexMinX
    q: 0

    while [true][
        'result ++ points\[p]

        q: (p + 1) % size points

        loop 0..dec size points 'i [
            if 2 = orientation points\[p] points\[i] points\[q] ->
                q: i
        ]

        p: q

        if p=indexMinX -> break
    ]

    return result
]

points: @[
    to :point [16 3],
    to :point [12 17],
    to :point [0 6],
    to :point @[neg 4 neg 6],
    to :point [16 6],
    to :point @[16 neg 7],
    to :point @[17 neg 4],
    to :point [5 19],
    to :point @[19 neg 8],
    to :point [3 16],
    to :point [12 13],
    to :point @[3 neg 4],
    to :point [17 5],
    to :point @[neg 3 15],
    to :point @[neg 3 neg 9],
    to :point [0 11],
    to :point @[neg 9 neg 3],
    to :point @[neg 4 neg 2],
    to :point [12 10]
]

hull: calculateConvexHull points
loop hull 'i ->
    print i