(printer-font "Courier")       ;; change printer font
(printer-page "ROSETTA CODE")  ;; starts a new page with nice header
(printer-writeln "Hello World!") ;; prints new line (not seen on stdout)


[ Hello world
  ===========

  A program for the EDSAC

  Can be used to print any character string:
  the string (including necessary *F and #F
  characters) should be stored in sequential
  memory addresses beginning at @+17.

  The last character of the string should be
  marked with a 1 in the least significant
  bit. This can be coded by using D in place
  of F, e.g. AD would be an 'A' as the last
  character

  Works with Initial Orders 2 ]

        T56K
        GK

[  0 ]  [email protected]    [ Print character        ]

[  1 ]  [email protected]    [ AND character with 1:  ]
        [email protected]    [ if the result is 1, we ]
        [email protected]    [ have reached the end   ]
        [email protected]    [ of the string          ]

        [email protected]    [ Modify the orders in   ]
        [email protected]      [ addresses @+0 and @+1  ]
        [email protected]    [ to point to the next   ]
        [email protected]      [ character              ]
        [email protected]
        [email protected]
        [email protected]
        [email protected]

[ 13 ]  ZF

[ 14 ]  PF
[ 15 ]  PD
[ 16 ]  P1F     [ NB Least significant bit
                  is not part of address,
                  so add 2 not 1         ]

[ 17 ]  *F      [ Letter shift           ]
        HF
        EF
        LF
        LF
        OF
        !F      [ Blank                  ]
        WF
        OF
        RF
        LF
        DF
        @F      [ Carriage return        ]
        &D      [ Line feed + 1          ]

        EZPF


! Hello World in ERRE language
PROGRAM HELLO
BEGIN
  !$REDIR
  PRINT("Hello World !")
  !$NOREDIR
END PROGRAM


( scratchpad ) USE: io.encodings.utf8
( scratchpad ) USE: io.launcher
( scratchpad ) "lpr" utf8 [ "Hello World!" print ] with-process-writer


\ No operating system, embedded device, printer output example

defer emit                                   \ deferred words in Forth are a place holder for an
                                             \ execution token (XT) that is assigned later.
                                             \ When executed the deferred word simply runs that assigned routine

: type ( addr count -- )                     \ type a string uses emit
       bounds ?do  i [email protected] emit   loop ;        \ type is used by all other text output words in the system

HEX
: CR   ( -- )  0A emit 0D emit ;             \ send a carriage return, linefeed pair with emit

\ memory mapped I/O addresses for the printer port
B02E   constant scsr                         \ serial control status register
B02F   constant scdr                         \ serial control data register

: printer-emit ( char -- )                   \ output 'char' to the printer serial port
         begin   scsr [email protected] 80 and  until       \ loop until the port shows a ready bit
         scdr C!                             \ C! (char store) writes a byte to an address
         20 ms ;                             \ 32 mS delay to prevent over-runs

: console-emit ( char -- )   ...             \ defined in the Forth system, usually assembler

\ vector control words
: >console     ['] console-emit is EMIT ;     \ assign the execution token of console-emit to EMIT
: >printer     ['] printer-emit is EMIT ;     \ assign the execution token of printer-emit to EMIT


+ No movement - thus overprint.
  (a blank) Advance one line.
0 Advance two lines - thus leave a blank line.
1 Page throw.


' FB 1.05.0 Win64

Open Lpt "Lpt:" As #1 '' prints to default printer
Print #1, "Hello World!"
Close #1


package main

import (
	"fmt"
	"os"
)

func main() {
	lp0, err := os.Create("/dev/lp0")

	if err != nil {
		panic(err)
	}

	defer lp0.Close()

	fmt.Fprintln(lp0, "Hello World!")
}


SET PRINT ON
SET CONSOLE OFF
? "Hello World!"
SET PRINT OFF
SET CONSOLE ON


import System.Process (ProcessHandle, runCommand)

main :: IO ProcessHandle
main = runCommand "echo \"Hello World!\" | lpr"


procedure main()
    write(open("/dev/lp0","w"),"Hello, world!")
end


import java.io.FileWriter;
import java.io.IOException;

public class LinePrinter {
  public static void main(String[] args) {
    try {
      FileWriter lp0 = new FileWriter("/dev/lp0");
      lp0.write("Hello World!");
      lp0.close();
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }
}


// This example runs on Node.js
var fs = require('fs');
// Assuming lp is at /dev/lp0
var lp = fs.openSync('/dev/lp0', 'w');
fs.writeSync(lp, 'Hello, world!\n');
fs.close(lp);


lineprinter = Sys.iswindows() ? "LPT3" : "/dev/lp0"
lp = open(lineprinter, "w")
write(lp, "Hello world")


import java.io.File

fun main(args: Array<String>) {
    val text = "Hello World!\n"
    File("/dev/lp0").writeText(text)
}


File_Write: '/dev/lp0', 'Hello world', -FileOverWrite;


Printer {
      \\ just change the current layer to Print Page
      \\ Using Layer { } we can change to basic console layer inside any layer
      Print "Hello World!"
}


commandstring = "echo Hello World!  | lpr -P Printer01"
Run[commandstring]


  fid = fopen('/dev/lp0');
  fprintf(fid,'Hello World!\n');
  fclose(fid);


LPR	EQU	18
STRING	EQU	2000
	ORIG	3000
START	IOC	0(LPR)
	OUT	STRING(LPR)
	HLT
	ORIG	STRING
	ALF	HELLO
	ALF	 WORL
	ALF	D!
	END	START


var lp = open("/dev/lp0", fmWrite)
lp.writeln "Hello World"
lp.close()


let () =
  let oc = open_out "/dev/lp0" in
  output_string oc "Hello world!\n";
  close_out oc ;;


File new("/dev/lp0") dup open(File.WRITE) "Hello world\n" << close


(define p (open-output-file "/dev/lp0"))
(when p
   (print-to p "Hello world!")
   (close-port p))


OUTPUT TO PRINTER.
PUT UNFORMATTED "Hello world!" SKIP.
OUTPUT CLOSE.


program testprn;
uses printer;
var i: integer;
    f: text;
begin
  writeln ( 'Test of printer unit' );
  writeln ( 'Writing to lst ...' );
  for i := 1 to 80 do
    writeln ( lst, 'This is line', i, '.' #13 );
  close ( lst );
  writeln ( 'Done.' );
  {$ifdef Unix }
  writeln ( 'Writing to pipe ...' );
  assignlst ( f, '|/usr/bin/lpr −m' );
  rewrite ( f );
  for i:= 1 to 80 do
    writeln ( f, 'This is line ', i, '.'#13 );
  close ( f );
  writeln ( 'Done.' )
  {$endif}
end.


open O, ">", "/dev/lp0";
print O "Hello World!\n";
close O;


integer fn = open(iff(platform()=WIN32?"PRN":"/dev/lp0"),"w")
if fn=-1 then
    puts(1,"some error")
else
    puts(fn,"Hello World!")
    close(fn)
    puts(1,"success!")
end if
{} = wait_key()


<?php
file_put_contents('/dev/lp0', 'Hello world!');
?>


main =>
    Printer = open("/dev/lp0", write),
    println(Printer, "Hello, world!"),
    flush(Printer),
    close(Printer).


(out '(lpr "-P" "Printer01")
   (prinl "Hello world") )


hello: procedure options(main);
   put skip list('Hello world.');
end hello;


<</PageSize [595 842]>> setpagedevice  % set page size to DIN A4
/Courier findfont                      % use Courier
12 scalefont setfont                   % 12 pt
28 802 moveto                          % 1 cm from the top and left edges
(Hello world) show                     % draw the string


:- initialization(main).

main :-
    open("/dev/lp0", write, Printer),
    writeln(Printer, "Hello, world!"),
    flush_output(Printer),
    close(Printer).


MyPrinter$ = LPRINT_GetDefaultPrinter()
If LPRINT_OpenPrinter(MyPrinter$)
  If LPRINT_StartDoc("Printing a RC-Task")
    LPRINT_Print(Chr(27) + "E") ; PCL reset for HP Printers
    LPRINT_PrintN("Hello World!")
    LPRINT_NewPage()
    LPRINT_EndDoc()
  EndIf
  LPRINT_ClosePrinter()
EndIf


lp = open("/dev/lp0")
lp.write("Hello World!\n")
lp.close()


#lang racket
(define (print text)
  ;; try lpr first
  (define lpr-exe (find-executable-path "lpr"))
  ;; otherwise use a special file
  (if lpr-exe
    (with-input-from-string (~a text "\n") (λ() (void (system* lpr-exe))))
    (with-output-to-file #:exists 'append
      (case (system-type) [(windows) "PRN"] [else "/dev/lp0"])
      (λ() (displayln text)))))
(print "Hello World!")


my $lp = open '/dev/lp0', :w;
$lp.say: 'Hello World!';
$lp.close;


/*REXX program prints a string to the  (DOS) line printer  via redirection to a printer.*/
$= 'Hello World!'                                /*define a string to be used for output*/
'@ECHO'   $    ">PRN"                            /*stick a fork in it,  we're all done. */


lp = fopen("/dev/lp0","w")  fputs(lp,"Hello world!")  fclose(lp)


      Fqsysprt   O    F   80        printer
      C                   except
      C                   seton                                        LR
      Oqsysprt   E
      O                                           11 'Hello world'


open("| lpr", "w") { |f| f.puts "Hello World!" }


use std::fs::OpenOptions;
use std::io::Write;

fn main() {
    let file = OpenOptions::new().write(true).open("/dev/lp0").unwrap();
    file.write(b"Hello, World!").unwrap();
}


import java.awt.print.PrinterException
import scala.swing.TextArea

object LinePrinter extends App {
  val (show, context) = (false, "Hello, World!")
  try // Default Helvetica, 12p
    new TextArea(context) {
      append(" in printing.")
      peer.print(null, null, show, null, null, show)
    }
  catch {
    case ex: PrinterException => ex.getMessage()
  }
  println("Document printed.")
}


(call-with-output-file "/dev/lp0"
  (lambda (printer)
    (write "Hello World!" printer)))


$ include "seed7_05.s7i";

const proc: main is func
  local
    var file: lp is STD_NULL;
  begin
    lp := open("/dev/lp0", "w");
    writeln(lp, "Hello world!");
    close(lp);
  end func;


Sys.open(\var fh, '>', '/dev/lp0') \
    && fh.say("Hello World!")      \
    && fh.close


BEGIN
   OUTTEXT("Hello World!");
   OUTIMAGE
END


s := PrinterStream defaultPrinter new.
s nextPutLine:'Hello, world'.
s close


import Foundation

let out = NSOutputStream(toFileAtPath: "/dev/lp0", append: true)
let data = "Hello, World!".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
out?.open()
out?.write(UnsafePointer<UInt8>(data!.bytes), maxLength: data!.length)
out?.close()


# Use the default printer queue, with lp(1) or lpr(1).
#  1. The system must have a printer queue.
#  2. The printer queue must understand plain text.
#  3. System V has lp(1). BSD has lpr(1).
#     CUPS has both lp(1) and lpr(1).
#
echo 'Hello World!' | lp
echo 'Hello World!' | lpr

# Use a character device.
#  1. The device must understand plain text.
#  2. You must have write permission for the device.
#  3. Some systems have /dev/lp0, /dev/lp1, ...
#  4. BSD has /dev/lpt0, /dev/lpt1, ... for the parallel ports;
#     and /dev/ulpt0, /dev/ulpt1, ... for the USB printers.
# Note that intermingling can occur if two processes write to the device at the
# same time. Using the print spooler method above avoids this problem,
#
echo 'Hello World!' >/dev/lp0
echo 'Hello World!' >/dev/lpt0
echo 'Hello World!' >/dev/ulpt0


call-with-output-file "/dev/lp0"
  λ : printer
      write "Hello World!" printer


/* hello_world_line_printer.wren */

class C {
    foreign static lprint(s)
}

C.lprint("Hello World!")


;Assemble with: tasm, tlink /t
;assume direction bit is clear (so si increments)
        .model  tiny
        .code
        org     100h
start:  mov     si, offset msg  ;point to message
        jmp     pr20

pr10:   mov     ah, 0           ;write character to printer
        mov     dx, 0           ;LPT1
        int     17h
pr20:   lodsb                   ;al, ds:[si++]
        cmp     al, 0           ;terminator?
        jne     pr10            ;loop if not
        ret                     ;return to OS

msg     db      "Hello World!", 0ch, 0  ;0ch = form feed (for laser printer)
        end     start


   create file helloword64.s
   compile it with : as -o helloword64.o helloword.s
   link  it with   : ld -o helloword64 helloword64.o -e main
   execute it      :  helloword64


GNAT Community
--------------

This contains the GNAT Community edition.

The packages for the native platforms contain:

  - the GNAT compiler toolchain
  - the SPARK Ada verification and prover toolset
  - the Libadalang library
  - the GNAT Studio IDE

The packages for the embedded platforms (ARM and RISC-V) only contain the
GNAT compiler toolchain for that target, so we recommend installing the
native package as well.

Installing
----------

On Windows:

  Simply run the .exe and follow the instructions.

On Linux:

  You will need to make the package executable before running it. In a command
  prompt, execute

     chmod +x path_to_the_package-bin

  then execute the package.

Automated installation
----------------------

To automate the installation, use the scripts provided here:

  https://github.com/AdaCore/gnat_community_install_script

Using
-----
                                                                                1,14
To start using the tools in command-line mode, you will need to add

   <install_prefix>/bin

to your PATH environment variable. Alternatively, you can simply launch

   <install_prefix>/bin/gnatstudio

and GNAT Studio will automatically add itself to the PATH - it will also
find the cross compiler, if you have installed everything in the default
locations. Note that GNAT Studio will add this at the *end* of the PATH,
meaning that it will find first any other GNAT installations that you
have in your PATH.

Platform-specific notes
-----------------------

== OpenSUSE: use the system ld ==

On OpenSUSE, the ld shipped with GNAT Community is not compatible
with the system libraries: use the system-provided ld instead, by
removing the file

   libexec/gcc/x86_64-pc-linux-gnu/8.3.1/ld

from your installation.

== Fedora ==

If developer packages are not yet installed, you might need to
install extra packages, by executing the following in a terminal:

  sudo dnf install make
  sudo dnf install ncurses-compat-libs

== Flashing to boards on Linux ==

To flash boards (such as the BBC micro:bit board) using the pyocd integration
in GNAT Studio under Linux, you might need privileges to access the USB ports,
without which the flash program will say "No connected boards".

To do this on Ubuntu, you can do it by creating (as administrator) the file
/etc/udev/rules.d/mbed.rules and add the line:

   SUBSYSTEM=="usb",MODE:="666"

then restarting the service by doing

   sudo udevadm control --reload
   sudo udevadm trigger


main: (
  printf($"Goodbye, World!"l$)
)


   create file helloword.s
   compile it with : as -o helloword.o helloword.s
   link  it with   : ld -o helloword helloword.o -e main
   execute it      :  helloword


PROGRAM:MYPROGRM
:.HELLO
:Disp "HELLO, WORLD!",i


#include <iostream>
int main() {
    using namespace std;
    cout << "Hello, World!" << endl;
    return 0;
}


    = "Hello world!"%string
    : string


import std.stdio;

void main()
{
    writeln("Hello world!");
}


;; This is a comment
;; Type in the following -uncommented- line in the input text area, and press [RETURN]
;; or click onto the "Eval" button
;; Auto-completion : You will notice that after "(di" , EchoLisp proposes "(display" :
;; Press the [TAB] key to accept

(display "Hello, World" "color:blue")


class
   APPLICATION
create
   make
feature
   make
      do
         print ("Hello World!")
      end
end


public program()
{
    console.writeLine("Hello world")
}


$ echo '"Hello world!"' | jq .

C:\ echo "Hello world!" | jq .


1. Use a web browser to go to http://juliabox.com. With email or Google signin, sign up for a free account.
    1a.(optional) JuliaBox has Julia tutorials. You will find them in the default file directories when JuliaBox first loads.
    1b. (optional) download and install Julia from https://julialang.org/

2. Start a JuliaBox session and choose "New" then "Julia 1.0 ."

3. Type in the box: println("Hello world")

4. Choose the |> symbol to run that line of Julia code.


The minimal installation is straightforward. Go to this URL:

   - http://lambdaway.free.fr/lambdaspeech/?view=download

• 1) download the ~25kb archive,
• 2) unzip the archive, you get a ~100kb folder named "archive",
• 3) rename it for instance "my_wiki", avoiding spaces and esoteric characters,
• 4) open your FTP tool and upload the folder to your web account.

Your wiki "my_wiki" is ready! Now:

• 1) open any modern web browser and go to "my_wiki" in your web account,
• 2) the start page displays "Hello World",
• 3) click on the title "start" to open the edit menu,
• 4) in the editor frame, under the first line containing

  _h1 Hello World

write for instance:

  _p This is my first sentence, a new paragraph has been added.

• 5) then choose "save" in the menu.

Congratulations, your first web page is published.


io.write("Hello world, from ",_VERSION,"!\n")


WINEPREFIX="$HOME/prefix32" WINEARCH=win32 wine wineboot


def sayHello():
    traceln("Hello World")
sayHello()


 using System.Console;

 class Hello {
     static Main() : void {
         WriteLine("Goodbye, world.");
     }
 }


=head1 Obtaining perl

On the majority of UNIX and UNIX-like operating systems
(Linux, Solaris, AIX, HPUX, et cetera), perl will already be installed.
Mac OS X also ships with perl.
Note that "Perl" refers to the language
while "perl" refers to the interpreter used to run Perl programs.

Windows does not ship with perl. Instead, you will have to install one of
the following perl distributions:

=over 4

=item Strawberry Perl

L<Strawberry Perl|http://strawberryperl.com/>: A 100% Open Source Perl for
Windows that is exactly the same as Perl everywhere else; this includes using
modules from CPAN, without the need for binary packages.

=item DWIM Perl for Windows

L<DWIM Perl for Windows|http://dwimperl.com/windows.html>: A 100% Open Source
Perl for Windows, based on Strawberry Perl.
It aims to include as many useful CPAN modules as possible.

=item ActiveState Perl

L<http://www.activestate.com/activeperl/downloads>

=back

Links and further instructions on installation can be found on
L<http://www.perl.org/get.html>.

Once perl is installed, the task of printing "Hello, World!" is quite simple.
From the command line, first check if your environment's C<PATH> variable
knows where to find perl.
On most systems, this can be achieved by entering C<which perl>;
if it spits out something like F</usr/bin/perl>, you're good to go!
If it tells you

    which: no perl in (...)

it means you need to add perl to your environment's C<PATH> variable.
This is done on most systems by entering

    export PATH=$PATH:[...]

where [...] is the full path to your perl installation (usually /usr/bin/perl).

If you do not have the C<which> command, you can probably just type C<perl>
to see if it fires up the perl interpreter.
If it does, press Ctrl+D to exit it and proceed.
Otherwise, perform the steps above to add perl to your PATH variable.

Once perl is installed, one-liners can be executed from the command line
by invoking perl with the C<-e> switch.
    $ perl -e 'print "Hello, World!\n";'
To create a script file that's more permanent, it can be put in a text file.
The name can be anything, but F<.pl> is encouraged.
The #!/usr/bin/perl at the beginning is called the shebang line;
if the operating system supports it, it tells where to find the perl interpreter.
If the script is run with C<perl>, this line will be ignored--
this is for invoking the file as an executable.

=cut

#!/usr/bin/perl
print "Hello, World!\n";


To run:   \This is a comment
Start up.
Write "Hello World!" to the console.
wAIt fOr tHe eScApE kEY.   \Plain English is case-insensitive
Shut down.


class HelloWorld
	**Prints "Goodbye, World!"**

	on start

		print "Goodbye, World!"


/*REXX program to greet the world enthusiastically. */
say "Hello world!"


sayHello()

func sayHello
     see "Hello World" + nl


fn main() {
    println!("Hello world!");
}


Transcript open.
Transcript show: 'Hello world'.


#lang transd

mainModule: {
  _start: (lambda (textout "Hello, World!"))
}


#include <CtrlLib/CtrlLib.h>
// submitted by Aykayayciti (Earl Lamont Montgomery)

using namespace Upp;

class GoodbyeWorld : public TopWindow {
	MenuBar menu;
	StatusBar status;

	void FileMenu(Bar& bar);
	void MainMenu(Bar& bar);
	void About();

public:
	typedef GoodbyeWorld CLASSNAME;

	GoodbyeWorld();
};

void GoodbyeWorld::About()
{
	PromptOK("{{[email protected] [@9= This is the]::@2 [[email protected] Ultimate`+`+ Goodbye World sample}}");
}

void GoodbyeWorld::FileMenu(Bar& bar)
{
	bar.Add("About..", THISBACK(About));
	bar.Separator();
	bar.Add("Exit", THISBACK(Close));
}

void GoodbyeWorld::MainMenu(Bar& bar)
{
	menu.Add("File", THISBACK(FileMenu));
}

GoodbyeWorld::GoodbyeWorld()
{
	AddFrame(menu);
	AddFrame(status);
	menu.Set(THISBACK(MainMenu));
	status = "So long from the Ultimate++ !";
}

GUI_APP_MAIN
{
	SetLanguage(LNG_ENGLISH);
	GoodbyeWorld().Run();
}


Arch Linux : $ yay -S uasm
   or        $ sudo pamac install uasm
Other Distros: Use your package manager
Windows: [http://www.terraspace.co.uk/uasm.html]


// - Install zig from https://ziglang.org/download/.
// - Extract into your path
// - `zig run newbie.zig`
const std = @import("std");

pub fn main() void {
    // If you only want to quickly debug things and panic on failure,
    // you can use `debug.print` to print to standard error
    // Do not use debug code in production.
    std.debug.print("Hello, World!\n");
}


with AWS; use AWS;
with AWS.Response;
with AWS.Server;
with AWS.Status;
with Ada.Text_IO; use Ada.Text_IO;
procedure HelloHTTP is
   function CB (Request : Status.Data) return Response.Data is
      pragma Unreferenced (Request);
   begin
      return Response.Build ("text/html", "Hello world!");
   end CB;
   TheServer : Server.HTTP;
   ch : Character;
begin
   Server.Start (TheServer, "Rosettacode",
      Callback => CB'Unrestricted_Access, Port => 8080);
   Put_Line ("Press any key to quit."); Get_Immediate (ch);
   Server.Shutdown (TheServer);
end HelloHTTP;


void
serve(dispatch w, file s, list colors)
{
    file i, o;
    date d;

    accept(i, o, s, 0);
    f_(o, "HTTP/1.1 200 OK\n"
"Content-Type: text/html; charset=UTF-8\n\n"
"<!DOCTYPE html><title>Bye-bye baby bye-bye</title>"
""
"
Goodbye, world!
\n");

    # chrome won't show the page if we close right away.  we'll close in 2s.
    d.now;
    d.offset(2, 0);
    w_schedule(w, d, f_close, i);
}

integer
main(void)
{
    dispatch w;
    file s;

    tcpip_listen(s, 8080, 0);
    w_watch(w, s, serve, w, s, list("blue", "green", "red", "yellow"));
    w_press(w);

    return 0;
}


// Hello world! mode Server

#include <hopper.h>
main:
   fd=0,fdc=0,message=""

   {"HTTP/1.1 200 OK\n","Content-Type: text/html; charset=UTF-8\n\n"}cat
   {"<!DOCTYPE html><title>Bye-bye baby bye-bye</title>"},cat
   {""}cat
   {"
Goodbye, world!
\n"}cat,
   mov(message)

/* Open socket in localhost (by default) */
/* Accept 5 conections (there are also 5 by default, if you put "any weá" there) */
   {5,8080}socket (OPENTCPSRV), mov(fd)

/* accept conection & send message */
   accept(fd), mov(fdc)
   {message},send(fdc)

/* close all */
   {fdc}socket(CLOSESOCK)
   {fd}socket(CLOSESOCK)

exit(0)


serv: httprun[8080; {"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nGoodbye, World!"}]


serve.port:8080 [ GET "/" -> "Goodbye, World!" ]


TCPStartup()
$socket = TCPListen("0.0.0.0",8080)
$string = "Goodbye, World!"
While 1
   Do
	  $newConnection = TCPAccept($socket)
	  Sleep(1)
   Until $newConnection <> -1
   $content = TCPRecv($newConnection, 2048)
   If StringLen($content) > 0 Then
	  TCPSend($newConnection, Binary("HTTP/1.1 200 OK" & @CRLF))
	  TCPSend($newConnection, Binary("Content-Type: text/html" & @CRLF))
	  TCPSend($newConnection, Binary("Content-Length: "& BinaryLen($string) & @CRLF & @CRLF))
	  TCPSend($newConnection, $string)
   EndIf
   TCPCloseSocket($newConnection)
WEnd


#!/usr/bin/gawk -f
     BEGIN {
       RS = ORS = "\r\n"
       HttpService = "/inet/tcp/8080/0/0"
       Hello = "" \
               "<TITLE>A Famous Greeting</TITLE>" \
               "
Hello, world
"
       Len = length(Hello) + length(ORS)
       print "HTTP/1.0 200 OK"          |& HttpService
       print "Content-Length: " Len ORS |& HttpService
       print Hello                      |& HttpService
       while ((HttpService |& getline) > 0)
          continue;
       close(HttpService)
     }


' Define HTTP constants
CONST New$ = CHR$(13) & NL$
CONST Sep$ = CHR$(13) & NL$ & CHR$(13) & NL$
CONST Msg$ = "BaCon web greeting
Goodbye, World!
"

' Get our IP
Ip$ = "localhost"
PRINT "Connect from browser '", Ip$, ":8080'."

' Ignore child signals to avoid zombie processes
SIGNAL SIG_IGN, SIGCHLD

' Open listening port
OPEN Ip$ & ":8080" FOR SERVER AS mynet

' Keep receiving requests
WHILE TRUE

    ' Handle for newly incoming connection
    fd = ACCEPT(mynet)

    ' Incoming connection -> create background process
    spawn = FORK

    ' We are in the child
    IF spawn = 0 THEN

        ' Get the request
        REPEAT
            RECEIVE dat$ FROM fd
            PRINT dat$
        UNTIL RIGHT$(dat$, 4) = Sep$

        ' Reply that we're OK
        SEND "HTTP/1.1 200 Ok" & New$ & "Content-Length: " & STR$(LEN(Msg$)) & Sep$ & Msg$ TO fd

        ' Close connection
        CLOSE SERVER fd

        ' End this process
        ENDFORK
    ENDIF
WEND


INSTALL @lib$+"SOCKLIB"
      PROC_initsockets

      maxSess% = 8
      DIM sock%(maxSess%-1), rcvd$(maxSess%-1), Buffer% 255

      ON ERROR PRINT REPORT$ : PROC_exitsockets : END
      ON CLOSE PROC_exitsockets : QUIT

      port$ = "8080"
      host$ = FN_gethostname
      PRINT "Host name is " host$

      listen% = FN_tcplisten(host$, port$)
      PRINT "Listening on port ";port$

      REPEAT
        socket% = FN_check_connection(listen%)
        IF socket% THEN
          FOR i% = 0 TO maxSess%-1
            IF sock%(i%) = 0 THEN
              sock%(i%) = socket%
              rcvd$(i%) = ""
              PRINT "Connection on socket "; sock%(i%) " opened"
              EXIT FOR
            ENDIF
          NEXT i%
          listen% = FN_tcplisten(host$, port$)
        ENDIF

        FOR i% = 0 TO maxSess%-1
          IF sock%(i%) THEN
            res% = FN_readsocket(sock%(i%), Buffer%, 256)
            IF res% >= 0 THEN
              Buffer%?res% = 0
              rcvd$(i%) += $$Buffer%
              IF LEFT$(rcvd$(i%),4) = "GET " AND ( \
              \ RIGHT$(rcvd$(i%),4) = CHR$13+CHR$10+CHR$13+CHR$10 OR \
              \ RIGHT$(rcvd$(i%),4) = CHR$10+CHR$13+CHR$10+CHR$13 OR \
              \ RIGHT$(rcvd$(i%),2) = CHR$10+CHR$10 ) THEN
                rcvd$(i%) = ""
                IF FN_writelinesocket(sock%(i%), "HTTP/1.0 200 OK")
                IF FN_writelinesocket(sock%(i%), "Content-type: text/html")
                IF FN_writelinesocket(sock%(i%), "")
                IF FN_writelinesocket(sock%(i%), "<title>Hello World!</title>")
                IF FN_writelinesocket(sock%(i%), "
Hello World!
")
                IF FN_writelinesocket(sock%(i%), "")
                PROC_closesocket(sock%(i%))
                PRINT "Connection on socket " ; sock%(i%) " closed (local)"
                sock%(i%) = 0
              ENDIF
            ELSE
              PROC_closesocket(sock%(i%))
              PRINT "Connection on socket " ; sock%(i%) " closed (remote)"
              sock%(i%) = 0
            ENDIF
          ENDIF
        NEXT i%

        WAIT 0
      UNTIL FALSE
      END


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>

char response[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=UTF-8\r\n\r\n"
"<!DOCTYPE html><title>Bye-bye baby bye-bye</title>"
""
"
Goodbye, world!
\r\n";

int main()
{
  int one = 1, client_fd;
  struct sockaddr_in svr_addr, cli_addr;
  socklen_t sin_len = sizeof(cli_addr);

  int sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    err(1, "can't open socket");

  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));

  int port = 8080;
  svr_addr.sin_family = AF_INET;
  svr_addr.sin_addr.s_addr = INADDR_ANY;
  svr_addr.sin_port = htons(port);

  if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
    close(sock);
    err(1, "Can't bind");
  }

  listen(sock, 5);
  while (1) {
    client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
    printf("got connection\n");

    if (client_fd == -1) {
      perror("Can't accept");
      continue;
    }

    write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
    close(client_fd);
  }
}


using System.Text;
using System.Net.Sockets;
using System.Net;

namespace WebServer
{
    class GoodByeWorld
    {
        static void Main(string[] args)
        {
            const string msg = "\n\nGoodbye, world!\n\n\n";
            const int port = 8080;
            bool serverRunning = true;

            TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
            tcpListener.Start();

            while (serverRunning)
            {
                Socket socketConnection = tcpListener.AcceptSocket();
                byte[] bMsg = Encoding.ASCII.GetBytes(msg.ToCharArray(), 0, (int)msg.Length);
                socketConnection.Send(bMsg);
                socketConnection.Disconnect(true);
            }
        }
    }
}


(ns goodbye-world.handler
  (:require [compojure.core :refer :all]
            [compojure.handler :as handler]
            [compojure.route :as route]))

(defroutes app-routes
  (GET "/" [] "Goodbye, World!")
  (route/resources "/")
  (route/not-found "Not Found"))

(def app
  (handler/site app-routes))


(ql:quickload :hunchentoot)
(defpackage :hello-web (:use :cl :hunchentoot))
(in-package :hello-web)

(define-easy-handler (hello :uri "/") () "Goodbye, World!")

(defparameter *server* (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 8080)))


require "http/server"

server = HTTP::Server.new do |context|
    context.response.print "Goodbye World"
end

server.listen(8080)


import std.socket, std.array;

ushort port = 8080;

void main() {
  Socket listener = new TcpSocket;
  listener.bind(new InternetAddress(port));
  listener.listen(10);

  Socket currSock;

  while (null !is (currSock = listener.accept())) {
    currSock.sendTo(replace(q"EOF
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

  <title>Hello world</title>
  Goodbye, World!

EOF", "\n", "\r\n"));
    currSock.close();
  }
}


import 'dart:io';

main() async {
  var server = await HttpServer.bind('127.0.0.1', 8080);

  await for (HttpRequest request in server) {
    request.response
      ..write('Hello, world')
      ..close();
  }
}


program HelloWorldWebServer;

{$APPTYPE CONSOLE}

uses SysUtils, IdContext, IdCustomHTTPServer, IdHTTPServer;

type
  TWebServer = class
  private
    FHTTPServer: TIdHTTPServer;
  public
    constructor Create;
    destructor Destroy; override;
    procedure HTTPServerCommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
  end;

constructor TWebServer.Create;
begin
  FHTTPServer := TIdHTTPServer.Create(nil);
  FHTTPServer.DefaultPort := 8080;
  FHTTPServer.OnCommandGet := HTTPServerCommandGet;
  FHTTPServer.Active := True;
end;

destructor TWebServer.Destroy;
begin
  FHTTPServer.Active := False;
  FHTTPServer.Free;
  inherited Destroy;
end;

procedure TWebServer.HTTPServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ContentText := 'Goodbye, World!';
end;

var
  lWebServer: TWebServer;
begin
  lWebServer := TWebServer.Create;
  try
    Writeln('Delphi Hello world/Web server ');
    Writeln('Press Enter to quit');
    Readln;
  finally
    lWebServer.Free;
  end;
end.


//compile with dylan.NET 11.5.1.2 or later!!
#refstdasm "mscorlib.dll"
#refstdasm "System.dll"

import System.Text
import System.Net.Sockets
import System.Net

assembly helloweb exe
ver 1.1.0.0

namespace WebServer

    class public GoodByeWorld

        method public static void main(var args as string[])

            var msg as string = c"\n\nGoodbye, world!\n\n\n"
            var port as integer = 8080
            var serverRunning as boolean = true

            var tcpListener as TcpListener = new TcpListener(IPAddress::Any, port)
            tcpListener::Start()

            do while serverRunning
                var socketConnection as Socket = tcpListener::AcceptSocket()
                var bMsg as byte[] = Encoding::get_ASCII()::GetBytes(msg::ToCharArray(), 0, msg::get_Length())
                socketConnection::Send(bMsg)
                socketConnection::Disconnect(true)
            end do

        end method

    end class

end namespace


-module( hello_world_web_server ).

-export( [do/1, httpd_start/2, httpd_stop/1, task/0] ).

do( _Data ) ->
  {proceed, [{response,{200,"Goodbye, World!"}}]}.

httpd_start( Port, Module ) ->
  Arguments = [{bind_address, "localhost"}, {port, Port}, {ipfamily, inet},
    {modules, [Module]},
    {server_name,erlang:atom_to_list(Module)}, {server_root,"."}, {document_root,"."}],
  {ok, Pid} = inets:start( httpd, Arguments, stand_alone ),
  Pid.

httpd_stop( Pid ) ->
  inets:stop( stand_alone, Pid ).

task() ->
  Pid = httpd_start( 8080, ?MODULE ),
  timer:sleep( 30000 ),
  httpd_stop( Pid ).


using web
using wisp

const class HelloMod : WebMod // provides the content
{
  override Void onGet ()
  {
    res.headers["Content-Type"] = "text/plain; charset=utf-8"
    res.out.print ("Goodbye, World!")
  }
}

class HelloWeb
{
  Void main ()
  {
    WispService // creates the web service
    {
      port = 8080
      root = HelloMod()
    }.start

    while (true) {} // stay running
  }
}


program http_example
   implicit none
   character (len=:), allocatable :: code
   character (len=:), allocatable :: command
   logical :: waitForProcess

   ! Execute a Node.js code
   code = "const http = require('http'); http.createServer((req, res) => &
   {res.end('Hello World from a Node.js server started from Fortran!')}).listen(8080);"

   command = 'node -e "' // code // '"'
   call execute_command_line (command, wait=waitForProcess)

end program http_example


program HelloWorldServer;
{$mode objfpc}{$H+}
uses
  Classes, fphttpserver;

Type
  TTestHTTPServer = Class(TFPHTTPServer)
  public
    procedure HandleRequest(Var ARequest: TFPHTTPConnectionRequest;
                            Var AResponse : TFPHTTPConnectionResponse); override;
  end;

Var
  Serv : TTestHTTPServer;

procedure TTestHTTPServer.HandleRequest(var ARequest: TFPHTTPConnectionRequest;
  var AResponse: TFPHTTPConnectionResponse);
Var
  F : TStringStream;
begin
  F:=TStringStream.Create('Hello,World!');
  try
    AResponse.ContentLength:=F.Size;
    AResponse.ContentStream:=F;
    AResponse.SendContent;
    AResponse.ContentStream:=Nil;
  finally
    F.Free;
  end;
end;

begin
  Serv:=TTestHTTPServer.Create(Nil);
  try
    Serv.Threaded:=False;
    Serv.Port:=8080;
    Serv.AcceptIdleTimeout:=1000;
    Serv.Active:=True;
  finally
    Serv.Free;
  end;
end.


native java.io.PrintWriter
native java.net.ServerSocket

val port = 8080
val listener = ServerSocket( port )

printf( 'Listening at port %1$d\n', port )

forever
  socket = listener.accept()
  PrintWriter( socket.getOutputStream(), true ).println( 'hello world' )
  socket.shutdownOutput()
  socket.close()


#javaj#

   <frames> oConsole

#listix#

      MICOHTTP, START, myServer, 8080

   <GET />
      //
      //  Goodbye world!
      //


/**
 * Based on https://wiki.gnome.org/Projects/Genie/GIONetworkingSample
 * Based on an example of Jezra Lickter http://hoof.jezra.net/snip/nV
 *
 * valac --pkg gio-2.0 --pkg gee-0.8 webserver.gs
 * ./webserver
 */
[indent=8]
uses
        GLib
        Gee

init
        var ws = new WebServer()
        ws.run()

struct Request
        full_request : string
        path : string
        query : string

struct Response
        status_code : string
        content_type : string
        data : string

class WebServer

        def run()
                port : uint16 = 8080
                tss : ThreadedSocketService = new ThreadedSocketService(100)
                ia : InetAddress = new InetAddress.any(SocketFamily.IPV4)
                isaddr : InetSocketAddress = new InetSocketAddress(ia, port)
                try
                        tss.add_address(isaddr, SocketType.STREAM, SocketProtocol.TCP, null, null);
                except e : Error
                        stderr.printf("%s\n", e.message)
                        return
                // add connection handler
                tss.run.connect( connection_handler )

                ml : MainLoop = new MainLoop()
                tss.start()
                stdout.printf("Serving on port %d\n", port)
                ml.run()

        def connection_handler ( conn : SocketConnection ) : bool
                first_line : string = ""
                size : size_t = 0;
                request : Request = Request()
                dis : DataInputStream = new DataInputStream (conn.input_stream)
                dos : DataOutputStream = new DataOutputStream (conn.output_stream)
                try
                        first_line = dis.read_line(out size)
                        // here you could analyze request information
                        var parts = first_line.split(" ");
                        if parts.length > 1 do request.full_request = parts[1]
                except e : Error
                        stderr.printf("%s\n", e.message)
                response : Response = Response()
                response.status_code = "HTTP/1.1 200 OK\n"
                response.content_type = "text/html"
                response.data = "
Goodbye, World!
"
                serve_response ( response, dos )
                return false

        def serve_response ( response : Response, dos : DataOutputStream )
                try
                        dos.put_string (response.status_code)
                        dos.put_string ("Server: Genie Socket\n")
                        dos.put_string("Content-Type: %s\n".printf(response.content_type))
                        dos.put_string("Content-Length: %d\n".printf(response.data.length))
                        dos.put_string("\n");//this is the end of the return headers
                        dos.put_string(response.data)
                except e : Error
                        stderr.printf("%s\n", e.message)


package main

import (
  "fmt"
  "log"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintln(w, "Goodbye, World!")
  })
  log.Fatal(http.ListenAndServe(":8080", nil))
}


{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString.Char8 ()
import Data.Conduit ( ($$), yield )
import Data.Conduit.Network ( ServerSettings(..), runTCPServer )

main :: IO ()
main = runTCPServer (ServerSettings 8080 "127.0.0.1") $ const (yield response $$)
  where response = "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"


WebRequest := Object clone do(
    handleSocket := method(aSocket,
      aSocket streamWrite("Goodbye, World!")
      aSocket close
    )
)

WebServer := Server clone do(
    setPort(8080)
    handleSocket := method(aSocket,
        WebRequest clone asyncSend(handleSocket(aSocket))
    )
)

WebServer start


import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class HelloWorld{
  public static void main(String[] args) throws IOException{
    ServerSocket listener = new ServerSocket(8080);
    while(true){
      Socket sock = listener.accept();
      new PrintWriter(sock.getOutputStream(), true).
                println("Goodbye, World!");
      sock.close();
    }
  }
}


var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Goodbye, World!\n');
}).listen(8080, '127.0.0.1');


prompt$ jsish
# require('Jsi_Websrv');
1.01
# Jsi_Websrv('', {server:true, port:8080, pageStr:'Goodbye, World!'});

...other terminal...

prompt$ curl http://localhost:8080/page
Goodbye, World!prompt$ curl http://localhost:8080/page
Goodbye, World!


using HttpServer
server = Server() do req, res
    "Goodbye, World!"
end
run(server, 8080)


import java.io.PrintWriter
import java.net.ServerSocket

fun main(args: Array<String>) {
    val listener = ServerSocket(8080)
    while(true) {
        val sock = listener.accept()
        PrintWriter(sock.outputStream, true).println("Goodbye, World!")
        sock.close()
    }
}


local(server) = net_tcp
handle => { #server->close }
#server->bind(8080) & listen & forEachAccept => {
   local(con) = #1

   split_thread => {
      handle => { #con->close }
      local(request) = ''
      // Read in the request in chunks until you have it all
      {
         #request->append(#con->readSomeBytes(8096))
         not #request->contains('\r\n\r\n')? currentCapture->restart
      }()

      local(response) = 'HTTP/1.1 200 OK\r\n\
            Content-Type: text/html; charset=UTF-8\r\n\r\n\
            Goodbye, World!'
      #con->writeBytes(bytes(#response))
   }
}


local socket = require "socket"
local headers = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: %d\r\n\r\n%s"
local content = "<!doctype html><html><title>Goodbye, World!</title><h1>Goodbye, World!"
local server = assert(socket.bind("localhost", 8080))
repeat
   local client = server:accept()
   local ok = client:send(string.format(headers, #content, content))
   client:close()
until not client or not ok
server:close()


listener =
 SocketListen["127.0.0.1:8080",
  Function[{assoc},
   With[{client = assoc["SourceSocket"]},
    WriteString[client,
     "HTTP/1.0 200 OK\nContent-Length: 16\n\nGoodbye, World!\n"];
    Close[client]]]]
SystemOpen["http://127.0.0.1:8080"]


MODULE access;

FROM  InOut   IMPORT  WriteString, WriteLn;

BEGIN
   WriteString ("Content-Type : text/plain");
   WriteLn;
   WriteLn;
   WriteString ("Hello web wide world.");
   WriteLn
END access.


/* NetRexx */
options replace format comments java crossref symbols binary

class RHelloWorldWebServer public

  properties public constant
    isTrue = boolean (1 == 1)
    isFalse = boolean (1 \== 1)
    greeting1 = "Goodbye, World!"
    greeting2 = '' -
      || 'HTTP/1.1 200 OK\r\n' -
      || 'Content-Type: text/html; charset=UTF-8\r\n\r\n' -
      || '<?xml version="1.0" encoding="UTF-8"?>\r\n' -
      || '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n' -
      || '\r\n' -
      || '\r\n' -
      || '<title>Hello</title>\r\n' -
      || '\r\n' -
      || '\r\n' -
      || '\r\n' -
      || '
' || greeting1 || '
\r\n' -
      || '\r\n' -
      || '\r\n' -
      || ''

  properties static inheritable
    terminate = isFalse -- TODO: provide a less draconian means to terminate the listener loop

  method main(args = String[]) public static signals IOException
    listener = ServerSocket(8080)
    loop label listener forever
      if terminate then leave listener
      sock = listener.accept()
      PrintWriter(sock.getOutputStream(), isTrue).println(greeting2)
      sock.close()
      end listener
    return


import asynchttpserver, asyncdispatch

proc cb(req: Request) {.async.} =
  await req.respond(Http200, "Hello, World!")

asyncCheck newAsyncHttpServer().serve(Port(8080), cb)
runForever()


use Net;
use Concurrency;

bundle Default {
  class GoodByeWorld {
    function : Main(args : String[]) ~ Nil {
      server := TCPSocketServer->New(8080);
      if(server->Listen(5)) {
        while(true) {
          client := server->Accept();
          client->WriteString("\n\nGoodbye, world!\n\n\n");
          client->Close();
        };
      };
      server->Close();
    }
  }
}


let try_finalise f x finally y =
  let res = try f x with e -> finally y; raise e in
  finally y;
  res

let rec restart_on_EINTR f x =
  try f x with Unix.Unix_error (Unix.EINTR, _, _) -> restart_on_EINTR f x

let double_fork_treatment server service (client_descr, _ as client) =
  let treat () =
    match Unix.fork () with
    | 0 ->
        if Unix.fork () <> 0 then exit 0;
        Unix.close server; service client; exit 0
    | k ->
        ignore (restart_on_EINTR (Unix.waitpid []) k)
  in
  try_finalise treat () Unix.close client_descr

let install_tcp_server_socket addr =
  let s = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
  try
    Unix.bind s addr;
    Unix.listen s 10;
    s
  with e -> Unix.close s; raise e

let tcp_server treat_connection addr =
  ignore (Sys.signal Sys.sigpipe Sys.Signal_ignore);
  let server_sock = install_tcp_server_socket addr in
  while true do
    let client = restart_on_EINTR Unix.accept server_sock in
    treat_connection server_sock client
  done

let server () =
  let port = 8080 in
  let host = (Unix.gethostbyname (Unix.gethostname())).Unix.h_addr_list.(0) in
  let addr = Unix.ADDR_INET (host, port) in
  let treat sock (client_sock, client_addr as client) =
    let service (s, _) =
      let response = "\
        HTTP/1.1 200 OK\r\n\
        Content-Type: text/html; charset=UTF-8\r\n\r\n\
        <title>Goodbye, world!</title>\
        \

Goodbye, world!
\r\n"
      in
      Unix.write s response 0 (String.length response);
    in
    double_fork_treatment sock service client
  in
  tcp_server treat addr

let _ =
  Unix.handle_unix_error server ()


(import (lib http))

(http:run 8080 (lambda (fd request headers send close)
   (send "HTTP/1.0 200 OK\n"
         "Connection: close\n"
         "Content-Type: text/html; charset=UTF-8\n"
         "Server: " (car *version*) "/" (cdr *version*)
         "\n\n"

         "
Goodbye, World!
"
         (ref request 1) ": " (ref request 2)
         "
" headers "")
   (close #t)
))


server = one_page_server("Hello", -> <>Goodbye, world</>)


use Socket;

my $port = 8080;
my $protocol = getprotobyname( "tcp" );

socket( SOCK, PF_INET, SOCK_STREAM, $protocol ) or die "couldn't open a socket: $!";
  # PF_INET to indicate that this socket will connect to the internet domain
  # SOCK_STREAM indicates a TCP stream, SOCK_DGRAM would indicate UDP communication

setsockopt( SOCK, SOL_SOCKET, SO_REUSEADDR, 1 ) or die "couldn't set socket options: $!";
  # SOL_SOCKET to indicate that we are setting an option on the socket instead of the protocol
  # mark the socket reusable

bind( SOCK, sockaddr_in($port, INADDR_ANY) ) or die "couldn't bind socket to port $port: $!";
  # bind our socket to $port, allowing any IP to connect

listen( SOCK, SOMAXCONN ) or die "couldn't listen to port $port: $!";
  # start listening for incoming connections

while( accept(CLIENT, SOCK) ){
  print CLIENT "HTTP/1.1 200 OK\r\n" .
               "Content-Type: text/html; charset=UTF-8\r\n\r\n" .
               "<title>Goodbye, world!</title>Goodbye, world!\r\n";
  close CLIENT;
}


-- demo\rosetta\SimpleHttpServer.exw
without js
include builtins\sockets.e
constant MAX_QUEUE      = 100,
         ESCAPE         = #1B,
         response = substitute("""
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>

  <title>Bye-bye baby bye-bye</title>

Goodbye, world!

""","\n","\r\n")

puts(1,"server started, open http://localhost:8080/ in browser or curl, press Esc or Q to quit\n")
atom sock = socket(AF_INET,SOCK_STREAM,NULL),
     pSockAddr = sockaddr_in(AF_INET, "", 8080)
if bind(sock, pSockAddr)=SOCKET_ERROR then crash("bind (%v)",{get_socket_error()}) end if
if listen(sock,MAX_QUEUE)=SOCKET_ERROR then crash("listen (%v)",{get_socket_error()}) end if
while not find(get_key(),{ESCAPE,'q','Q'}) do
    {integer code} = select({sock},{},{},250000)    -- (0.25s)
    if code=SOCKET_ERROR then crash("select (%v)",{get_socket_error()}) end if
    if code>0 then  -- (not timeout)
        atom peer = accept(sock),
             ip = getsockaddr(peer)
        {integer len, string request} = recv(peer)
        printf(1,"Client IP: %s\n%s\n",{ip_to_string(ip),request})
        if length(request)>3 and request[1..4]="GET " then
            integer bytes_sent = send(peer,response)
            printf(1,"%d bytes successfully sent\n",bytes_sent)
        end if
        shutdown(peer, SD_SEND) -- tell curl it's over
        peer = closesocket(peer)  --    (as does this)
    end if
end while
sock = closesocket(sock)
WSACleanup()


<?php
                     // AF_INET6 for IPv6  // IP
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die('Failed to create socket!');
                  // '127.0.0.1' to limit only to localhost // Port
socket_bind($socket, 0,                                        8080);
socket_listen($socket);

$msg = '<title>Goodbye, world!</title>Goodbye, world!';

for (;;) {
    // @ is used to stop PHP from spamming with error messages if there is no connection
    if ($client = @socket_accept($socket)) {
        socket_write($client, "HTTP/1.1 200 OK\r\n" .
               "Content-length: " . strlen($msg) . "\r\n" .
               "Content-Type: text/html; charset=UTF-8\r\n\r\n" .
               $msg);
    }
    else usleep(100000); // limits CPU usage by sleeping after doing every request
}
?>


(html 0 "Bye" NIL NIL
   "Goodbye, World!" )


void handle_request(Protocols.HTTP.Server.Request request)
{
    request->response_and_finish( ([ "data":"Goodbye, World!",
                                     "type":"text/html" ]) );
}

int main()
{
    Protocols.HTTP.Server.Port(handle_request, 8080);
    return -1; // -1 is a special case that retirns control to the backend
}


use "net"

actor Main
  new create(env: Env) =>
    try TCPListener(env.root as AmbientAuth,
                Listener,
                "127.0.0.1", "8080")
    else env.err.print("unable to use the network")
    end

// Boilerplate code, create a TCP listener on a socket
class Listener is TCPListenNotify

  new iso create() => None

  fun ref listening(_: TCPListener ref) => None

  fun ref not_listening(listen: TCPListener ref) => listen.close()

  fun ref connected(listen: TCPListener ref): TCPConnectionNotify iso^ =>
    Server

// HTTP server that handles the TCP connections
class val Server is TCPConnectionNotify

  // Empty ctor
  new iso create() => None

  // Impl for when server accepts the client request
  fun accepted(_: TCPConnection ref) => None

  // Impl for when server receives client data
  fun ref received(conn: TCPConnection ref, _: Array[U8] iso, _: USize)
  : Bool
  =>
    // handle request
    conn.write("HTTP/1.1 200 OK\r\n\r\n")
    conn.write("
")
    conn.write("Goodbye, World!")
    conn.write("
")
    conn.dispose()
    false

  // Impl for when client closes the connection
  fun ref closed(conn: TCPConnection ref) => conn.dispose()

  // Impl for when client fails to connect to all possible addresses for the server
  fun ref connect_failed(_: TCPConnection ref) => None


% The following modules are used in the main module to start a server.
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).

% The following module is used in every module that describes a page.
:- use_module(library(http/html_write)).

% Main entry point: starts the server on port 8080.
server :- http_server(http_dispatch, [port(8080)]).

% Defines the handler for the root URI /.
:- http_handler('/', say_goodbye, []).

% Defines the actual page content.
% In this case we're returning a page with the title "Howdy" and the content,
% wrapped in

 tags, "Goodbye, World!".
say_goodbye(_Request) :- reply_html_page([title('Howdy')],
                                   [h1('Goodbye, World!')]).


If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !")
  End
EndIf

Port = 8080

If CreateNetworkServer(0, Port)
  Repeat
    Delay(1)
    SEvent = NetworkServerEvent()
    If SEvent
      ClientID = EventClient()
      Select SEvent
        Case #PB_NetworkEvent_Data
          SendNetworkData(ClientID,@"Goodbye, World!",Len("Goodbye, World!"))
          CloseNetworkConnection(ClientID)
      EndSelect
    EndIf
  ForEver
Else
  MessageRequester("Error", "Can't create the server (port in use ?).")
EndIf


from wsgiref.simple_server import make_server

def app(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    yield b"
Goodbye, World!
"

server = make_server('127.0.0.1', 8080, app)
server.serve_forever()


library(httpuv)

runServer("0.0.0.0", 5000,
	list(
		call = function(req) {
		  list(status = 200L,	headers = list('Content-Type' = 'text/html'), body = "Hello world!")
	        }
	)
)


#lang racket
(require web-server/servlet web-server/servlet-env)
(define (start req) (response/xexpr "Goodbye, World!"))
(serve/servlet start #:port 8080 #:servlet-path "/")


my $listen = IO::Socket::INET.new(:listen, :localhost<localhost>, :localport(8080));
loop {
    my $conn = $listen.accept;
    my $req =  $conn.get ;
    $conn.print: "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nGoodbye, World!\r\n";
    $conn.close;
}


Class HTTPSock
Inherits TCPSocket
  Event Sub DataAvailable()
    Dim headers As New InternetHeaders
    headers.AppendHeader("Content-Length", Str(LenB("Goodbye, World!")))
    headers.AppendHeader("Content-Type", "text/plain")
    headers.AppendHeader("Content-Encoding", "identity")
    headers.AppendHeader("Connection", "close")
    Dim data As String = "HTTP/1.1 200 OK" + EndOfLine.Windows + headers.Source + EndOfLine.Windows + EndOfLine.Windows + "Goodbye, World!"
    Me.Write(data)
    Me.Close
  End Sub
End Class

Class HTTPServ
Inherits ServerSocket
  Event Sub AddSocket() As TCPSocket
    Return New HTTPSock
  End Sub
End Class

Class App
Inherits Application
  Event Sub Run(Args() As String)
    Dim sock As New HTTPServ
    sock.Port = 8080
    sock.Listen()
    While True
      App.DoEvents
    Wend
  End Sub
End Class


/* HTTP hello server */
response.1 = 'HTTP/1.1 200 OK' || '0D0A'X,
          || 'Connection: close' || '0D0A'X,
          || 'Content-Type: text/html' || '0D0A0D0A'X
response.2 = '<!DOCTYPE html>' || '0A'X,
          || '<title>Hello, Rosetta</title>' || '0A'X,
          || '
Goodbye, World!
' || '0A'X,
          || '' || '0A'X

DO FOREVER
    ADDRESS SYSTEM 'nc -l 8080' WITH INPUT STEM response.
END


Load "guilib.ring"

cResponse = "HTTP/1.1 200 OK\r\n" +
               "Content-Type: text/html\r\n\r\n" +
               "<title>Goodbye, world!</title>" +
               "Goodbye, world!"

cResponse = substr(cResponse,"\r\n",char(13)+char(10))

new qApp {
	oServer = new Server { Server() }
	exec()
}

Class Server

        win1 lineedit1
        oTcpServer oTcpClient
        cOutput = ""

        func server

                win1 = new qwidget()

                lineedit1 = new qtextedit(win1) {
                        setGeometry(150,50,200,300)
                }

                win1 {
                        setwindowtitle("Server")
                        setgeometry(450,100,400,400)
                        show()
                }

                oTcpServer = new qTcpServer(win1) {
                        setNewConnectionEvent("oServer.pNewConnection()")
                        oHostAddress = new qHostAddress()
                        oHostAddress.SetAddress("127.0.0.1")
                        listen(oHostAddress,8080)
                }
                cOutput = "Server Started" + nl +
                           "listen to port 8080" + nl

                lineedit1.settext(cOutput)

        Func pNewConnection

                oTcpClient = oTcpServer.nextPendingConnection()
                while not oTcpClient.waitForReadyRead(100) end
                cOutput += "Accept Connection" + nl
                lineedit1.settext(cOutput)
                oTcpClient {
                        write(cResponse,len(cResponse))
                        flush()
                        waitforbyteswritten(300000)
                        close()
                }


require 'webrick'
server = WEBrick::HTTPServer.new(:Port => 8080)
server.mount_proc('/') {|request, response| response.body = "Goodbye, World!"}
trap("INT") {server.shutdown}
server.start


use std::net::{Shutdown, TcpListener};
use std::thread;
use std::io::Write;

const RESPONSE: &'static [u8] = b"HTTP/1.1 200 OK\r
Content-Type: text/html; charset=UTF-8\r\n\r
<!DOCTYPE html><title>Bye-bye baby bye-bye</title>

Goodbye, world!
\r";

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();

    for stream in listener.incoming() {
        thread::spawn(move || {
            let mut stream = stream.unwrap();
            match stream.write(RESPONSE) {
                Ok(_) => println!("Response sent!"),
                Err(e) => println!("Failed sending response: {}!", e),
            }
            stream.shutdown(Shutdown::Write).unwrap();
        });
    }
}


use "http.salm" : "http.si";

/* Don't do any logging. */
procedure log(...) { };

simple_http_server(8080, procedure(header, connection)
  { respond_text(connection, "Goodbye, World!"); });


import java.io.PrintWriter
import java.net.ServerSocket

object HelloWorld extends App {

  val text =

        <TITLE>Hello world </TITLE>

 Goodbye, World!

val port = 8080
  val listener = new ServerSocket(port)
   printf("Listening at port %1$d", port)

  while (true) {
    val sock = listener.accept()
    new PrintWriter(sock.getOutputStream(), true).println(text)
    sock.close()
  }
}


$ include "seed7_05.s7i";
  include "listener.s7i";

const proc: main is func
  local
    var listener: aListener is listener.value;
    var file: sock is STD_NULL;
  begin
    aListener := openInetListener(8080);
    listen(aListener, 10);
    while TRUE do
      sock := accept(aListener);
      write(sock, "HTTP/1.1 200 OK\r\n\
                  \Content-Type: text/html; charset=UTF-8\r\n\
                  \\r\n\
                  \Hello, world!\n");
      close(sock);
    end while;
  end func;


var port = 8080;
var protocol = Socket.getprotobyname("tcp");

var sock = (Socket.open(Socket.PF_INET, Socket.SOCK_STREAM, protocol) || die "couldn't open a socket: #{$!}");
  # PF_INET to indicate that this socket will connect to the internet domain
  # SOCK_STREAM indicates a TCP stream, SOCK_DGRAM would indicate UDP communication

sock.setsockopt(Socket.SOL_SOCKET, Socket.SO_REUSEADDR, 1) || die "couldn't set socket options: #{$!}";
  # SOL_SOCKET to indicate that we are setting an option on the socket instead of the protocol
  # mark the socket reusable

sock.bind(Socket.sockaddr_in(port, Socket.INADDR_ANY)) || die "couldn't bind socket to port #{port}: #{$!}";
  # bind our socket to $port, allowing any IP to connect

sock.listen(Socket.SOMAXCONN) || die "couldn't listen to port #{port}: #{$!}";
  # start listening for incoming connections

while (var client = sock.accept) {
  client.print ("HTTP/1.1 200 OK\r\n" +
               "Content-Type: text/html; charset=UTF-8\r\n\r\n" +
               "<title>Goodbye, world!</title>" +
               "Goodbye, world!\r\n");
  client.close;
}


Smalltalk loadPackage:'stx:goodies/webServer'. "usually already loaded"
|myServer service|

myServer := HTTPServer startServerOnPort:8082.
service := HTTPPluggableActionService new.
service
    register:[:request |
        self halt: 'debugging'.
        request reply:'
Hello World
'
    ]
    as:'hello'.
service linkNames:#('/' ).
service registerServiceOn: myServer.
myServer start.


val txt = Word8VectorSlice.full (Byte.stringToBytes  "hello world!"   ) ;

fun serve listener portnr =
 let
  fun next () =
   let
    val (conn, conn_addr) = Socket.accept listener
   in
    case  Posix.Process.fork () of
        NONE   =>
             (
	      Socket.sendVec(conn, txt); Socket.close conn ;
              OS.Process.exit OS.Process.success
             )
       | _     =>
             (
	      Socket.close conn ;next ()
	     )
    end
  in (
   Socket.Ctl.setREUSEADDR(listener, true);
   Socket.bind(listener, INetSock.any portnr );
   Socket.listen(listener, 9);
   next ()
   )
  end               handle x => (Socket.close listener; raise x)
;


proc accept {chan addr port} {
    while {[gets $chan] ne ""} {}
    puts $chan "HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/plain\n"
    puts $chan "Goodbye, World!"
    close $chan
}
socket -server accept 8080
vwait forever


while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo 'Hello, World!'; } | nc -l 8080; done


with server_socket socket :port 4000
  accepting client :from socket
    making stdout outfile+fd.client
      prn "HTTP/1.0 200 OK"
      prn "Content-type: text/plain"
      prn ""
      prn "Hello, world!"


import "web" for Routes, App

Routes.GET("/") {
    return "Goodbye, World!"
}

App.run(8080)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Crossplatform(?) Web Server example using UASM's OO Language extention
;;
;; Linux Build:
;;   $ uasm -elf64 websrv.asm
;;   $ gcc -o websrv websrv.o -no-pie
;;  With MUSL libc
;;   $ musl-gcc -o websrv websrv.o -e main -nostartfiles -no-pie
;;
;; Windows Build:
;;   $ uasm64 -win64 websrv.asm
;;   $ link /machine:x64 /subsystem:console /release websrv.obj
;;         kernel32.lib msvcrt.lib ws2_32.lib
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

option casemap:none
option literals:on          ;; Usually on by default buuuuuut...

WIN64   equ 1
LIN64   equ 3

ifndef __WEBSRV_CLASS__
__WEBSERV_CLASS__   equ 1

    AF_INET     equ 2
    SOCK_STREAM equ 1
    INADDR_ANY  equ 0

    in_addr struct
        s_addr  dd ?
    in_addr ends

    sockaddr struct
        sa_family   dw ?
        sa_data     db 14 dup (?)
    sockaddr ends

    sockaddr_in struct
        sin_family  dw ?
        sin_port    dw ?
        sin_addr    in_addr <?>
        sin_zero    db 8 dup (?)
    sockaddr_in ends

    WSADATA struct
        wVersion        dw ?
        wHighVersion    dw ?
        iMaxSockets     dw ?
        iMaxUdpDg       dw ?
        szDescription   db 256 dup (?)
        szSystemStatus  db 128 dup (?)
        lpVendorInfo    dq ?
    WSADATA ends

    ;; Platform specific requirements etc..
    if @Platform eq WIN64
        ;;include/includelibs can be used here. But this works too.
        option dllimport:<kernel32>
            ExitProcess     proto ucode:dword
            HeapAlloc       proto fd:qword, flgs:dword, hlen:qword
            HeapFree        proto fd:qword, flgs:dword, lpmem:qword
            GetProcessHeap  proto
        option dllimport:<msvcrt>
            printf      proto fmt:qword, args:VARARG
            strlen      proto buff:qword
        option dllimport:<ws2_32>
            WSAStartup  proto ver:word, wsa:qword
            WSACleanup  proto wsa:qword
            closesocket proto fd:dword
            socket      proto d:dword, s:dword, prtl:dword
            bind        proto fd:dword, saddr:qword, slen:dword
            listen      proto fd:dword, blog:dword
            accept      proto fd:dword, caddr:qword, slen:qword
            send        proto fd:dword, buff:qword, blen:dword, flgs:dword
        option dllimport:none
        exit    equ ExitProcess
        close   equ closesocket
    elseif @Platform eq LIN64
        ;; Required proto from Libc stuff.
        malloc  proto SYSTEMV mem:qword         ;; Required by the class macros.
        free    proto SYSTEMV mem:qword         ;; It uses HeapAlloc on windows.
        printf  proto SYSTEMV fmt:qword, args:VARARG
        strlen  proto SYSTEMV buff:qword
        socket  proto SYSTEMV d:dword, s:dword, prtl:dword
        bind    proto SYSTEMV fd:dword, saddr:qword, slen:dword
        listen  proto SYSTEMV fd:dword, blog:dword
        accept  proto SYSTEMV fd:dword, saddr:qword, slen:qword
        send    proto SYSTEMV fd:dword, buff:qword, blen:dword, flgs:dword
        close   proto SYSTEMV fd:dword
        exit    proto SYSTEMV uexit:dword
    else
        ;; Could do some OSX or w/e specific crap, but I don't use
        ;; a Mac so, I dunno shit about it's API :]
    endif

    ;; Class definitions etc..
    CLASS websrv
        ;; Class Method definitions
        CMETHOD serve
    ENDMETHODS
        ;; Class Variables.
        if @Platform eq WIN64
            wsa  WSADATA <?>
        endif
        tmpl    db  "[websrv->%s] - %s",10,0
        http    db  "HTTP/1.1 200 OK",13,10,
                    "Content-Type: text/html; charset=UTF-8",13,10,13,10,
                    "<title>Goodbye</title>Goodbye, World!",0
        sock    dd 0
        port    dw 8080
    ENDCLASS

    pwebsrv typedef ptr websrv

    ;; Method implementation..
    ;   Syntax:
    ;       METHOD ClassName, MethodName, <ReturnType>, <USE extra regs for ret>, args..
    METHOD websrv, Init, <VOIDARG>, <>
        local x:sockaddr_in

        mov rbx, thisPtr            ;; Force the ThisPtr reference reg to be RBX 'cause of windoze
        assume rbx:ptr websrv       ;; its default is RCX, and RDI on linux. *shrugs*
        invoke printf, addr [rbx].tmpl,CSTR("init"), CSTR("Starting...")
        if @Platform eq WIN64
            invoke WSAStartup, 200h, addr [rbx].wsa
        endif
        invoke socket, AF_INET, SOCK_STREAM, 0
        .if rax == -1
            invoke printf, addr [rbx].tmpl, CSTR("init:ERROR"), CSTR("Socket() returned < 0")
            mov rax, rbx
            ret
        .endif
        mov [rbx].sock, eax
        invoke printf, CSTR("[websrv->init:socket] - %d",10), eax
        mov x.sin_family, AF_INET
        mov x.sin_addr.s_addr, INADDR_ANY
        mov ax, [rbx].port
        xchg al,ah
        mov x.sin_port, ax
        invoke bind, [rbx].sock, addr x, sizeof(x)
        .if eax == -1
            invoke printf, addr [rbx].tmpl, CSTR("init:ERROR") , CSTR("Bind failed.")
            xor eax, eax
            mov [rbx].sock, 0
            mov rax, rbx
            ret
        .endif
        invoke printf, addr [rbx].tmpl, CSTR("init"), CSTR("Bind successful.")
        mov rax, rbx
        assume rbx: nothing
        ret
    ENDMETHOD

    METHOD websrv, serve, <VOIDARG>, <>
        local tmp:qword
        local cfd:dword
        local x:sockaddr

        mov rbx, thisPtr
        assume rbx:ptr websrv
        .if [rbx].sock == 0
            ret
        .endif
        invoke printf, addr [rbx].tmpl,CSTR("serve"), CSTR("Listening for incomming connections")
        invoke listen, [rbx].sock, 5
        .if rax == -1
            invoke printf, addr [rbx].tmpl, CSTR("serve:ERROR"), CSTR("Listen() returned -1")
            ret
        .endif

        .while(1)
            mov tmp, sizeof(x)
            invoke accept, [rbx].sock, addr x, addr tmp
            .if eax == -1
                invoke printf, addr [rbx].tmpl, CSTR("serve:ERROR"), CSTR("Accept() returned -1")
                ret
            .endif
            mov cfd, eax
            invoke printf, addr [rbx].tmpl, CSTR("serve"), CSTR("Connection established.")
            invoke strlen, addr [rbx].http
            invoke send, cfd, addr [rbx].http, eax , 0
            invoke close, cfd
        .endw
        assume rbx:nothing
        ret
    ENDMETHOD

    METHOD websrv, Destroy, <VOIDARG>, <>
        mov rbx, thisPtr
        assume rbx:ptr websrv
        invoke printf, addr [rbx].tmpl,CSTR("destroy"), CSTR("Calling Close and exit.")
        invoke close,  [rbx].sock
        if @Platform eq WIN64
            invoke WSACleanup, addr [rbx].wsa
        endif
        assume rbx:nothing
        invoke exit, 0
        ret
    ENDMETHOD
endif                       ;; __WEBSRV_CLASS__

;; Start of main run code...
.code
main proc
    local server:ptr websrv

    mov server, _NEW(websrv)
    server->serve()
    _DELETE(server)
    ret
main endp
end


const PORT=8080;
const SERVLET_THREADS=4;

    // A class to process requests from clients (eg browsers)
    // in a thread. Requests are received via a pipe, which feeds
    // all Servlet threads.
class Servlet{
   fcn init(jobPipe){ self.launch(jobPipe); }
   fcn liftoff(jobPipe){
      while(1){    // read request, write response, repeat
         socket:=jobPipe.read();
         if(socket.wait(60) != 1)	// what is Chrome doing?
            { socket.close(); continue; }
         if (request:=socket.read())
	    try{ processRequest(request,socket); } catch{}
      }
   }
   fcn splashdown(h,e){ println("Servlet died before its time"); }
}

fcn processRequest(request,socket){
   response:=responseHeader();
   response+="Goodbye, World!";
   socket.write(response); socket.close();    // no Keep-Alive
}

fcn responseHeader(status=200,reason="OK"){
  String(
   "HTTP/1.0 ",status," ",reason,"\r\n",
   Time.Date.httpDate(),"\r\n"
   "Server: ZTWS (zkl)\r\n"
   "Connection: close\r\n"
   "Content-Type: text/html; charset=UTF-8\r\n"
   "\r\n")
}

      //////////////////// Start the server ///////////////////////
var jobPipe=Thread.Pipe();    // a queue of requests
do(SERVLET_THREADS){ Servlet(jobPipe) }  // start threads

    // Create the HTTP server listen socket
    // Sits here forever passing client HTTP connects to Servlets
serverSocket:=Network.TCPServerSocket.open(PORT);
println("HTTP server started at http://",
    serverSocket.hostname, ":", serverSocket.port);
serverSocket.listen(jobPipe);


F gcd(=u, =v)
   L v != 0
      (u, v) = (v, u % v)
   R abs(u)

F hero(a, b, c)
   V s = (a + b + c) / 2
   V a2 = s * (s - a) * (s - b) * (s - c)
   R I a2 > 0 {sqrt(a2)} E 0

F is_heronian(a, b, c)
   V x = hero(a, b, c)
   R x > 0 & fract(x) == 0

F gcd3(x, y, z)
   R gcd(gcd(x, y), z)

V MAXSIDE = 200
[(Int, Int, Int)] h
L(x) 1..MAXSIDE
   L(y) x..MAXSIDE
      L(z) y..MAXSIDE
         I (x + y > z) & gcd3(x, y, z) == 1 & is_heronian(x, y, z)
            h [+]= (x, y, z)

h = sorted(h, key' x -> (hero(x[0], x[1], x[2]), sum(x), (x[2], x[1], x[0])))

print(‘Primitive Heronian triangles with sides up to #.: #.’.format(MAXSIDE, h.len))
print("\nFirst ten when ordered by increasing area, then perimeter, then maximum sides:")
print(h[0.<10].map3((x, y, z) -> ‘  #14 perim: #3 area: #.’.format(String((x, y, z)), x + y + z, hero(x, y, z))).join("\n"))
print("\nAll with area 210 subject to the previous ordering:")
print(h.filter3((x, y, z) -> hero(x, y, z) == 210).map3((x, y, z) -> ‘  #14 perim: #3 area: #.’.format(String((x, y, z)), x + y + z, hero(x, y, z))).join("\n"))


with Ada.Containers.Indefinite_Ordered_Sets;
with Ada.Finalization;
with Ada.Text_IO; use Ada.Text_IO;
procedure Heronian is
   package Int_IO is new Ada.Text_IO.Integer_IO(Integer);
   use Int_IO;

   -- ----- Some math...
   function GCD (A, B : in Natural) return Natural is (if B = 0 then A else GCD (B, A mod B));

   function Int_Sqrt (N : in Natural) return Natural is
      R1 : Natural := N;
      R2 : Natural;
   begin
      if N <= 1 then
         return N;
      end if;
      loop
         R2 := (R1+N/R1)/2;
         if R2 >= R1 then
            return R1;
         end if;
         R1 := R2;
      end loop;
   end Int_Sqrt;

   -- ----- Defines the triangle with sides as discriminants and a constructor which will
   -- compute its other characteristics
   type t_Triangle (A, B, C : Positive) is new Ada.Finalization.Controlled with record
      Is_Heronian  : Boolean;
      Perimeter    : Positive;
      Area         : Natural;
   end record;

   overriding procedure Initialize (Self : in out t_Triangle) is
      -- Let's stick to integer computations, therefore a modified hero's formula
      -- will be used : S*(S-a)*(S-b)*(S-c) = (a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c)/16
      -- This will require long integers because at max side size, the product
      -- before /16 excesses 2^31
      Long_Product  : Long_Long_Integer;
      Short_Product : Natural;
   begin
      Self.Perimeter   := Self.A + Self.B + Self.C;
      Long_Product     :=   Long_Long_Integer(Self.Perimeter)
                          * Long_Long_Integer(- Self.A + Self.B + Self.C)
                          * Long_Long_Integer(  Self.A - Self.B + Self.C)
                          * Long_Long_Integer(  Self.A + Self.B - Self.C);
      Short_Product    := Natural(Long_Product / 16);
      Self.Area        := Int_Sqrt (Short_Product);
      Self.Is_Heronian := (Long_Product mod 16 = 0) and (Self.Area * Self.Area = Short_Product);
   end Initialize;

   -- ----- Ordering triangles with criteria (Area,Perimeter,A,B,C)
   function "<" (Left, Right : in t_Triangle) return Boolean is
     (Left.Area      < Right.Area      or else (Left.Area      = Right.Area      and then
     (Left.Perimeter < Right.Perimeter or else (Left.Perimeter = Right.Perimeter and then
     (Left.A         < Right.A         or else (Left.A         = Right.A         and then
     (Left.B         < Right.B         or else (Left.B         = Right.B         and then
      Left.C         < Right.C))))))));
   package Triangle_Lists is new Ada.Containers.Indefinite_Ordered_Sets (t_Triangle);
   use Triangle_Lists;

   -- ----- Displaying triangle characteristics
   Header : constant String := "  A   B   C Per  Area" & ASCII.LF & "---+---+---+---+-----";
   procedure Put_Triangle (Position : Cursor) is
      Triangle : constant t_Triangle := Element(Position);
   begin
      Put(Triangle.A, 3);
      Put(Triangle.B, 4);
      Put(Triangle.C, 4);
      Put(Triangle.Perimeter, 4);
      Put(Triangle.Area,      6);
      New_Line;
   end Put_Triangle;

   -- ----- Global variables
   Triangles : Set := Empty_Set;
   -- Instead of constructing two sets, or browsing all the beginning of the set during
   -- the second output, start/end cursors will be updated during the insertions.
   First_201 : Cursor := No_Element;
   Last_201  : Cursor := No_Element;

   procedure Memorize_Triangle (A, B, C : in Positive) is
      Candidate : t_Triangle(A, B, C);
      Position  : Cursor;
      Dummy     : Boolean;
   begin
      if Candidate.Is_Heronian then
         Triangles.Insert (Candidate, Position, Dummy);
         if Candidate.Area = 210 then
            First_201 := (if    First_201 = No_Element then Position
                          elsif Position < First_201   then Position
                          else  First_201);
            Last_201 :=  (if    Last_201  = No_Element then Position
                          elsif Last_201  < Position   then Position
                          else  Last_201);
         end if;
      end if;
   end Memorize_Triangle;

begin
   -- Loops restrict to unique A,B,C (ensured by A <= B <= C) with sides < 200 and for
   -- which a triangle is constructible : C is not greater than B+A (flat triangle)
   for A in 1..200 loop
      for B in A..200 loop
         for C in B..Integer'Min(A+B-1,200) loop
            -- Filter non-primitive triangles
            if GCD(GCD(A,B),C) = 1 then
               Memorize_Triangle (A, B, C);
            end if;
         end loop;
      end loop;
   end loop;

   Put_Line (Triangles.Length'Img & " heronian triangles found :");
   Put_Line (Header);
   Triangles.Iterate (Process => Put_Triangle'Access);
   New_Line;

   Put_Line ("Heronian triangles with area = 201");
   Put_Line (Header);
   declare
      Position : Cursor := First_201;
   begin
      loop
         Put_Triangle (Position);
         exit when Position = Last_201;
         Position := Next(Position);
      end loop;
   end;
end Heronian;


# mode to hold details of a Heronian triangle #
MODE HERONIAN = STRUCT( INT a, b, c, area, perimeter );
# returns the details of the Heronian Triangle with sides a, b, c or nil if it isn't one #
PROC try ht = ( INT a, b, c )REF HERONIAN:
    BEGIN
        REF HERONIAN    t := NIL;
        REAL            s  = ( a + b + c ) / 2;
        REAL area squared  = s * ( s - a ) * ( s - b ) * ( s - c );
        IF area squared > 0 THEN
            # a, b, c does form a triangle #
            REAL area      = sqrt( area squared );
            IF ENTIER area = area THEN
                # the area is integral so the triangle is Heronian #
                t := HEAP HERONIAN := ( a, b, c, ENTIER area, a + b + c )
            FI
        FI;
        t
    END # try ht # ;
# returns the GCD of a and b #
PROC gcd = ( INT a, b )INT: IF b = 0 THEN a ELSE gcd( b, a MOD b ) FI;
# prints the details of the Heronian triangle t #
PROC ht print = ( REF HERONIAN t )VOID:
     print( ( whole( a OF t, -4 ), whole( b OF t, -5 ), whole( c OF t, -5 ), whole( area OF t, -5 ), whole( perimeter OF t, -10 ), newline ) );
# prints headings for the Heronian Triangle table #
PROC ht title = VOID: print( ( "   a    b    c area perimeter", newline, "---- ---- ---- ---- ---------", newline ) );

BEGIN
    # construct ht as a table of the Heronian Triangles with sides up to 200 #
    [ 1 : 1000 ]REF HERONIAN ht;
    REF HERONIAN             t;
    INT                      ht count := 0;

    FOR c TO 200 DO
        FOR b TO c DO
            FOR a TO b DO
                IF gcd( gcd( a, b ), c ) = 1 THEN
                    t := try ht( a, b, c );
                    IF REF HERONIAN(t) ISNT REF HERONIAN(NIL) THEN
                        ht[ ht count +:= 1 ] := t
                    FI
                FI
            OD
        OD
    OD;

    # sort the table on ascending area, perimeter and max side length #
    # note we constructed the triangles with c as the longest side    #
    BEGIN
        INT          lower := 1, upper := ht count;
        WHILE upper        := upper - 1;
              BOOL swapped := FALSE;
              FOR i FROM lower TO upper DO
                  REF HERONIAN h := ht[ i     ];
                  REF HERONIAN k := ht[ i + 1 ];
                  IF area OF k < area OF h OR (   area OF k =  area OF h
                                              AND (  perimeter OF k <  perimeter OF h
                                                  OR (   perimeter OF k = perimeter OF h
                                                     AND c OF k < c OF h
                                                     )
                                                  )
                                              )
                  THEN
                      ht[ i     ] := k;
                      ht[ i + 1 ] := h;
                      swapped     := TRUE
                  FI
              OD;
              swapped
        DO SKIP OD;

        # display the triangles #
        print( ( "There are ", whole( ht count, 0 ), " Heronian triangles with sides up to 200", newline ) );
        ht title;
        FOR ht pos TO 10 DO ht print( ht( ht pos ) ) OD;
        print( ( " ...", newline ) );
        print( ( "Heronian triangles with area 210:", newline ) );
        ht title;
        FOR ht pos TO ht count DO
            REF HERONIAN t := ht[ ht pos ];
            IF area OF t = 210 THEN ht print( t ) FI
        OD
    END
END


begin
    % record to hold details of a Heronian triangle %
    record Heronian ( integer a, b, c, area, perimeter );
    % returns the details of the Heronian Triangle with sides a, b, c or nil if it isn't one %
    reference(Heronian) procedure tryHt( integer value a, b, c ) ;
    begin
        real                s, areaSquared, area;
        reference(Heronian) t;
        s           := ( a + b + c ) / 2;
        areaSquared := s * ( s - a ) * ( s - b ) * ( s - c );
        t           := null;
        if areaSquared > 0 then begin
            % a, b, c does form a triangle %
            area    := sqrt( areaSquared );
            if entier( area ) = area then begin
                % the area is integral so the triangle is Heronian %
                t := Heronian( a, b, c, entier( area ), a + b + c )
            end
        end;
        t
    end tryHt ;

    % returns the GCD of a and b %
    integer procedure gcd( integer value a, b ) ; if b = 0 then a else gcd( b, a rem b );

    % prints the details of the Heronian triangle t %
    procedure htPrint( reference(Heronian) value t ) ; write( i_w := 4, s_w := 1, a(t), b(t), c(t), area(t), "     ", perimeter(t) );
    % prints headings for the Heronian Triangle table %
    procedure htTitle ; begin write( "   a    b    c area perimeter" ); write( "---- ---- ---- ---- ---------" ) end;

    begin
        % construct ht as a table of the Heronian Triangles with sides up to 200 %
        reference(Heronian) array ht ( 1 :: 1000 );
        reference(Heronian)       t;
        integer                   htCount;

        htCount := 0;
        for c := 1 until 200 do begin
            for b := 1 until c do begin
                for a := 1 until b do begin
                    if gcd( gcd( a, b ), c ) = 1 then begin
                        t := tryHt( a, b, c );
                        if t not = null then begin
                            htCount       := htCount + 1;
                            ht( htCount ) := t
                        end
                    end
                end
            end
        end;

        % sort the table on ascending area, perimeter and max side length %
        % note we constructed the triangles with c as the longest side %
        begin
            integer             lower, upper;
            reference(Heronian) k, h;
            logical             swapped;
            lower := 1;
            upper := htCount;
            while begin
                upper   := upper - 1;
                swapped := false;
                for i := lower until upper do begin
                    h := ht( i     );
                    k := ht( i + 1 );
                    if area(k) < area(h) or (   area(k) =  area(h)
                                            and (  perimeter(k) <  perimeter(h)
                                                or (   perimeter(k) = perimeter(h)
                                                   and c(k)         < c(h)
                                                   )
                                                )
                                            )
                    then begin
                        ht( i     ) := k;
                        ht( i + 1 ) := h;
                        swapped     := true;
                    end
                end;
                swapped
            end
            do  begin end;
        end;

        % display the triangles %
        write( "There are ", htCount, " Heronian triangles with sides up to 200" );
        htTitle;
        for htPos := 1 until 10 do htPrint( ht( htPos ) );
        write( " ..." );
        write( "Heronian triangles with area 210:" );
        htTitle;
        for htPos := 1 until htCount do begin
            reference(Heronian) t;
            t := ht( htPos );
            if area(t) = 210 then htPrint( t )
        end
    end
end.


use framework "Foundation"

-- HERONIAN TRIANGLES --------------------------------------------------------

-- heroniansOfSideUpTo :: Int -> [(Int, Int, Int)]
on heroniansOfSideUpTo(n)
    script sideA
        on |λ|(a)
            script sideB
                on |λ|(b)
                    script sideC
                        -- primitiveHeronian :: Int -> Int -> Int -> Bool
                        on primitiveHeronian(x, y, z)
                            (x ≤ y and y ≤ z) and (x + y > z) and ¬
                                gcd(gcd(x, y), z) = 1 and ¬
                                isIntegerValue(hArea(x, y, z))
                        end primitiveHeronian

                        on |λ|(c)
                            if primitiveHeronian(a, b, c) then
                                {{a, b, c}}
                            else
                                {}
                            end if
                        end |λ|
                    end script

                    concatMap(sideC, enumFromTo(b, n))
                end |λ|
            end script

            concatMap(sideB, enumFromTo(a, n))
        end |λ|
    end script

    concatMap(sideA, enumFromTo(1, n))
end heroniansOfSideUpTo

-- TEST ----------------------------------------------------------------------
on run
    set n to 200

    set lstHeron to ¬
        sortByComparing({{"area", true}, {"perimeter", true}, {"maxSide", true}}, ¬
            map(triangleDimensions, heroniansOfSideUpTo(n)))

    set lstCols to {"sides", "perimeter", "area"}
    set lstColWidths to {20, 15, 0}
    set area to 210

    script areaFilter
        -- Record -> [Record]
        on |λ|(recTriangle)
            if area of recTriangle = area then
                {recTriangle}
            else
                {}
            end if
        end |λ|
    end script

    intercalate("\n \n", {("Number of triangles found (with sides <= 200): " & ¬
        length of lstHeron as string), ¬
        ¬
            tabulation("First 10, ordered by area, perimeter, longest side", ¬
                items 1 thru 10 of lstHeron, lstCols, lstColWidths), ¬
        ¬
            tabulation("Area = 210", ¬
                concatMap(areaFilter, lstHeron), lstCols, lstColWidths)})
end run

-- triangleDimensions :: (Int, Int, Int) ->
--       {sides: (Int, Int, Int),  area: Int, perimeter: Int, maxSize: Int}
on triangleDimensions(lstSides)
    set {x, y, z} to lstSides
    {sides:[x, y, z], area:hArea(x, y, z) as integer, perimeter:x + y + z, maxSide:z}
end triangleDimensions

-- hArea :: Int -> Int -> Int -> Num
on hArea(x, y, z)
    set s to (x + y + z) / 2
    set a to s * (s - x) * (s - y) * (s - z)

    if a > 0 then
        a ^ 0.5
    else
        0
    end if
end hArea

-- gcd :: Int -> Int -> Int
on gcd(m, n)
    if n = 0 then
        m
    else
        gcd(n, m mod n)
    end if
end gcd

-- TABULATION ----------------------------------------------------------------

-- tabulation :: [Record] -> [String] -> String -> [Integer] -> String
on tabulation(strLegend, lstRecords, lstKeys, lstWidths)
    script heading
        on |λ|(strTitle, iCol)
            set str to toTitle(strTitle)
            str & replicate((item iCol of lstWidths) - (length of str), space)
        end |λ|
    end script

    script lineString
        on |λ|(rec)
            script fieldString
                -- fieldString :: String -> Int -> String
                on |λ|(strKey, i)
                    set v to keyValue(strKey, rec)

                    if class of v is list then
                        set strData to ("(" & intercalate(", ", v) & ")")
                    else
                        set strData to v as string
                    end if

                    strData & replicate(space, (item i of (lstWidths)) - (length of strData))
                end |λ|
            end script

            tab & intercalate(tab, map(fieldString, lstKeys))
        end |λ|
    end script

    strLegend & ":" & linefeed & linefeed & ¬
        tab & intercalate(tab, ¬
        map(heading, lstKeys)) & linefeed & ¬
        intercalate(linefeed, map(lineString, lstRecords))
end tabulation

-- GENERIC FUNCTIONS ---------------------------------------------------------

-- concat :: [[a]] -> [a] | [String] -> String
on concat(xs)
    if length of xs > 0 and class of (item 1 of xs) is string then
        set acc to ""
    else
        set acc to {}
    end if
    repeat with i from 1 to length of xs
        set acc to acc & item i of xs
    end repeat
    acc
end concat

-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
    concat(map(f, xs))
end concatMap

-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
    if m > n then
        set d to -1
    else
        set d to 1
    end if
    set lst to {}
    repeat with i from m to n by d
        set end of lst to i
    end repeat
    return lst
end enumFromTo

-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from 1 to lng
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldl

-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
    set {dlm, my text item delimiters} to {my text item delimiters, strText}
    set strJoined to lstText as text
    set my text item delimiters to dlm
    return strJoined
end intercalate

-- isIntegerValue :: Num -> Bool
on isIntegerValue(n)
    {real, integer} contains class of n and (n = (n as integer))
end isIntegerValue

-- keyValue :: String -> Record -> Maybe String
on keyValue(strKey, rec)
    set ca to current application
    set v to (ca's NSDictionary's dictionaryWithDictionary:rec)'s objectForKey:strKey
    if v is not missing value then
        item 1 of ((ca's NSArray's arrayWithObject:v) as list)
    else
        missing value
    end if
end keyValue

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- replicate :: Int -> String -> String
on replicate(n, s)
    set out to ""
    if n < 1 then return out
    set dbl to s

    repeat while (n > 1)
        if (n mod 2) > 0 then set out to out & dbl
        set n to (n div 2)
        set dbl to (dbl & dbl)
    end repeat
    return out & dbl
end replicate

-- List of {strKey, blnAscending} pairs -> list of records -> sorted list of records

-- sortByComparing :: [(String, Bool)] -> [Records] -> [Records]
on sortByComparing(keyDirections, xs)
    set ca to current application

    script recDict
        on |λ|(x)
            ca's NSDictionary's dictionaryWithDictionary:x
        end |λ|
    end script
    set dcts to map(recDict, xs)

    script asDescriptor
        on |λ|(kd)
            set {k, d} to kd
            ca's NSSortDescriptor's sortDescriptorWithKey:k ascending:d selector:dcts
        end |λ|
    end script

    ((ca's NSArray's arrayWithArray:dcts)'s ¬
        sortedArrayUsingDescriptors:map(asDescriptor, keyDirections)) as list
end sortByComparing

-- toTitle :: String -> String
on toTitle(str)
    set ca to current application
    ((ca's NSString's stringWithString:(str))'s ¬
        capitalizedStringWithLocale:(ca's NSLocale's currentLocale())) as text
end toTitle


Primitive_Heronian_triangles(MaxSide){
	obj :=[]
	loop, % MaxSide {
		a := A_Index
		loop % MaxSide-a+1 {
			b := A_Index+a-1
			loop % MaxSide-b+1 {
				c := A_Index+b-1, s := (a+b+c)/2, Area := Sqrt(s*(s-a)*(s-b)*(s-c))
				if (Area = Floor(Area)) && (Area>0) && !obj[a/s, b/s, c/s]
					obj[a/s, b/s, c/s]:=1 ,res .= (res?"`n":"") StrReplace(Area, ".000000") "`t" a+b+c "`t" a ", " b ", " c
	}	}	}
	Sort, res, F Sort
	return res
}

Sort(x, y){
	x := StrSplit(x, "`t"), y := StrSplit(y, "`t")
	return x.1 > y.1 ? 1 : x.1 < y.1 ? -1 : x.2 > y.2 ? 1 : x.2 < y.2 ? -1 : 0
}


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

typedef struct{
	int a,b,c;
	int perimeter;
	double area;
}triangle;

typedef struct elem{
	triangle t;
	struct elem* next;
}cell;

typedef cell* list;

void addAndOrderList(list *a,triangle t){
	list iter,temp;
	int flag = 0;

	if(*a==NULL){
		*a = (list)malloc(sizeof(cell));
		(*a)->t = t;
		(*a)->next = NULL;
	}

	else{
		temp = (list)malloc(sizeof(cell));

			iter = *a;
			while(iter->next!=NULL){
				if(((iter->t.area<t.area)||(iter->t.area==t.area && iter->t.perimeter<t.perimeter)||(iter->t.area==t.area && iter->t.perimeter==t.perimeter && iter->t.a<=t.a))
				&&
				(iter->next==NULL||(t.area<iter->next->t.area || t.perimeter<iter->next->t.perimeter || t.a<iter->next->t.a))){
					temp->t = t;
					temp->next = iter->next;
					iter->next = temp;
					flag = 1;
					break;
				}

				iter = iter->next;
			}

			if(flag!=1){
				temp->t = t;
				temp->next = NULL;
				iter->next = temp;
			}
	}
}

int gcd(int a,int b){
	if(b!=0)
		return gcd(b,a%b);
	return a;
}

void calculateArea(triangle *t){
	(*t).perimeter = (*t).a + (*t).b + (*t).c;
	(*t).area = sqrt(0.5*(*t).perimeter*(0.5*(*t).perimeter - (*t).a)*(0.5*(*t).perimeter - (*t).b)*(0.5*(*t).perimeter - (*t).c));
}

list generateTriangleList(int maxSide,int *count){
	int a,b,c;
	triangle t;
	list herons = NULL;

	*count = 0;

	for(a=1;a<=maxSide;a++){
		for(b=1;b<=a;b++){
			for(c=1;c<=b;c++){
				if(c+b > a && gcd(gcd(a,b),c)==1){
					t = (triangle){a,b,c};
					calculateArea(&t);
					if(t.area/(int)t.area == 1){
						addAndOrderList(&herons,t);
						(*count)++;
					}
				}
			}
		}
	}

	return herons;
}

void printList(list a,int limit,int area){
	list iter = a;
	int count = 1;

	printf("\nDimensions\tPerimeter\tArea");

	while(iter!=NULL && count!=limit+1){
		if(area==-1 ||(area==iter->t.area)){
			printf("\n%d x %d x %d\t%d\t\t%d",iter->t.a,iter->t.b,iter->t.c,iter->t.perimeter,(int)iter->t.area);
			count++;
		}
		iter = iter->next;
	}
}

int main(int argC,char* argV[])
{
	int count;
	list herons = NULL;

	if(argC!=4)
		printf("Usage : %s <Max side, max triangles to print and area, -1 for area to ignore>",argV[0]);
	else{
		herons = generateTriangleList(atoi(argV[1]),&count);
		printf("Triangles found : %d",count);
		(atoi(argV[3])==-1)?printf("\nPrinting first %s triangles.",argV[2]):printf("\nPrinting triangles with area %s square units.",argV[3]);
		printList(herons,atoi(argV[2]),atoi(argV[3]));
		free(herons);
	}
	return 0;
}


using System;
using System.Collections.Generic;

namespace heron
{
    class Program{
        static void Main(string[] args){
            List<int[]> list = new List<int[]>();
            for (int c = 1; c <= 200; c++)
                for (int b = 1; b <= c; b++)
                    for (int a = 1; a <= b; a++)
                        if (gcd(a, gcd(b, c)) == 1 && isHeron(heronArea(a, b, c)))
                            list.Add(new int[] { a, b, c, a + b + c, (int)heronArea(a, b, c)});
            sort(list);
            Console.WriteLine("Number of primitive Heronian triangles with sides up to 200: " + list.Count + "\n\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:\nSides\t\t\tPerimeter\tArea");
            for(int i = 0; i < 10; i++)
                Console.WriteLine(list[i][0] + "\t" + list[i][1] + "\t" + list[i][2] + "\t" + list[i][3] + "\t\t" + list[i][4]);
            Console.WriteLine("\nPerimeter = 210\nSides\t\t\tPerimeter\tArea");
            foreach (int[] i in list)
                if (i[4] == 210)
                    Console.WriteLine(i[0] + "\t" + i[1] + "\t" + i[2] + "\t" + i[3] + "\t\t" + i[4]);
        }
        static bool isHeron(double heronArea){
            return heronArea % 1 == 0 && heronArea != 0;
        }
        static double heronArea(int a, int b, int c){
            double s = (a + b + c) / 2d;
            return Math.Sqrt(s * (s - a) * (s - b) * (s - c));
        }
        static int gcd(int a, int b){
            int remainder = 1, dividend, divisor;
            dividend = a > b ? a : b;
            divisor = a > b ? b : a;
            while (remainder != 0){
                remainder = dividend % divisor;
                if (remainder != 0){
                    dividend = divisor;
                    divisor = remainder;
                }
            }
            return divisor;
        }
        static void sort(List<int[]> list){
            int[] temp = new int[5];
            bool changed = true;
            while(changed){
                changed = false;
                for (int i = 1; i < list.Count; i++)
                    if (list[i][4] < list[i - 1][4] || list[i][4] == list[i - 1][4] && list[i][3] < list[i - 1][3]){
                        temp = list[i];
                        list[i] = list[i - 1];
                        list[i - 1] = temp;
                        changed = true;
                    }
            }
        }
    }
}


#include <algorithm>
#include <cmath>
#include <iostream>
#include <tuple>
#include <vector>

int gcd(int a, int b)
{
    int rem = 1, dividend, divisor;
    std::tie(divisor, dividend) = std::minmax(a, b);
    while (rem != 0) {
        rem = dividend % divisor;
        if (rem != 0) {
            dividend = divisor;
            divisor = rem;
        }
    }
    return divisor;
}

struct Triangle
{
    int a;
    int b;
    int c;
};

int perimeter(const Triangle& triangle)
{
    return triangle.a + triangle.b + triangle.c;
}

double area(const Triangle& t)
{
    double p_2 = perimeter(t) / 2.;
    double area_sq = p_2 * ( p_2 - t.a ) * ( p_2 - t.b ) * ( p_2 - t.c );
    return sqrt(area_sq);
}

std::vector<Triangle> generate_triangles(int side_limit = 200)
{
    std::vector<Triangle> result;
    for(int a = 1; a <= side_limit; ++a)
        for(int b = 1; b <= a; ++b)
            for(int c = a+1-b; c <= b; ++c) // skip too-small values of c, which will violate triangle inequality
            {
                Triangle t{a, b, c};
                double t_area = area(t);
                if(t_area == 0) continue;
                if( std::floor(t_area) == std::ceil(t_area) && gcd(a, gcd(b, c)) == 1)
                    result.push_back(t);
            }
    return result;
}

bool compare(const Triangle& lhs, const Triangle& rhs)
{
    return std::make_tuple(area(lhs), perimeter(lhs), std::max(lhs.a, std::max(lhs.b, lhs.c))) <
           std::make_tuple(area(rhs), perimeter(rhs), std::max(rhs.a, std::max(rhs.b, rhs.c)));
}

struct area_compare
{
    bool operator()(const Triangle& t, int i) { return area(t) < i; }
    bool operator()(int i, const Triangle& t) { return i < area(t); }
};

int main()
{
    auto tri = generate_triangles();
    std::cout << "There are " << tri.size() << " primitive Heronian triangles with sides up to 200\n\n";

    std::cout << "First ten when ordered by increasing area, then perimeter, then maximum sides:\n";
    std::sort(tri.begin(), tri.end(), compare);
    std::cout << "area\tperimeter\tsides\n";
    for(int i = 0; i < 10; ++i)
        std::cout << area(tri[i]) << '\t' << perimeter(tri[i]) << "\t\t" <<
                     tri[i].a << 'x' << tri[i].b << 'x' << tri[i].c << '\n';

    std::cout << "\nAll with area 210 subject to the previous ordering:\n";
    auto range = std::equal_range(tri.begin(), tri.end(), 210, area_compare());
    std::cout << "area\tperimeter\tsides\n";
    for(auto it = range.first; it != range.second; ++it)
        std::cout << area(*it) << '\t' << perimeter(*it) << "\t\t" <<
                     it->a << 'x' << it->b << 'x' << it->c << '\n';
}