Soloway's recurring rainfall: Difference between revisions
Content added Content deleted
(Added Algol 68) |
(→{{header|ALGOL 68}}: tweak) |
||
Line 78: | Line 78: | ||
BOOL valid := UPB s >= LWB s; # invalid if the string is empty # |
BOOL valid := UPB s >= LWB s; # invalid if the string is empty # |
||
FOR s pos FROM LWB s TO UPB s WHILE valid DO |
FOR s pos FROM LWB s TO UPB s WHILE valid DO |
||
IF s[ s pos ] |
IF valid := s[ s pos ] >= "0" AND s[ s pos ] <= "9" |
||
THEN |
THEN |
||
valid := FALSE # invalid characters # |
|||
ELSE |
|||
n *:= 10 +:= ( ABS s[ s pos ] - ABS "0" ) |
n *:= 10 +:= ( ABS s[ s pos ] - ABS "0" ) |
||
FI |
FI |
Revision as of 20:37, 10 September 2022
Soloway's recurring rainfall
You are encouraged to solve this task according to the task description, using any language you may know.
You are encouraged to solve this task according to the task description, using any language you may know.
Soloway's Recurring Rainfall is commonly used to asses general programming knowledge by requiring basic program structure, input/output, and program exit procedure.
The problem:
Write a program that will read in integers and output their average. Stop reading when the value 99999 is input.
References:
- http://cs.brown.edu/~kfisler/Pubs/icer14-rainfall/icer14.pdf
- https://www.curriculumonline.ie/getmedia/8bb01bff-509e-48ed-991e-3ab5dad74a78/Seppletal-2015-DoweknowhowdifficulttheRainfallProblemis.pdf
- https://en.wikipedia.org/wiki/Moving_average#Cumulative_average
Ada
with Ada.Text_IO;
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;
with Ada.Integer_Text_IO;
with Ada.IO_Exceptions;
procedure RecurringRainfall is
Current_Average : Float := 0.0;
Current_Count : Integer := 0;
Input_Integer : Integer;
-- Recursively attempt to get a new integer
function Get_Next_Input return Integer is
Input_Integer : Integer;
Clear_String : Ada.Strings.Unbounded.Unbounded_String;
begin
Ada.Text_IO.Put("Enter rainfall int, 99999 to quit: ");
Ada.Integer_Text_IO.Get(Input_Integer);
return Input_Integer;
exception
when Ada.IO_Exceptions.Data_Error =>
Ada.Text_IO.Put_Line("Invalid input");
-- We need to call Get_Line to make sure we flush the kb buffer
-- The pragma is to ignore the fact that we are not using the result
pragma Warnings (Off, Clear_String);
Clear_String := Ada.Text_IO.Unbounded_IO.Get_Line;
-- Recursively call self -- it'll break when valid input is hit
-- We disable the infinite recursion because we're intentionally
-- doing this. It will "break" when the user inputs valid input
-- or kills the program
pragma Warnings (Off, "infinite recursion");
return Get_Next_Input;
pragma Warnings (On, "infinite recursion");
end Get_Next_Input;
begin
loop
Input_Integer := Get_Next_Input;
exit when Input_Integer = 99999;
Current_Count := Current_Count + 1;
Current_Average := Current_Average + (Float(1) / Float(Current_Count))*Float(Input_Integer) - (Float(1) / Float(Current_Count))*Current_Average;
Ada.Text_IO.Put("New Average: ");
Ada.Text_IO.Put_Line(Float'image(Current_Average));
end loop;
end RecurringRainfall;
ALGOL 68
BEGIN # read a sequence of integers, terminated by 99999 and outpout their average #
INT end value = 99999;
INT sum := 0;
INT count := 0;
WHILE
INT n := 0;
WHILE
STRING s;
print( ( "Enter rainfall (integer) or ", whole( end value, 0 ), " to quit: " ) );
read( ( s, newline ) );
BOOL valid := UPB s >= LWB s; # invalid if the string is empty #
FOR s pos FROM LWB s TO UPB s WHILE valid DO
IF valid := s[ s pos ] >= "0" AND s[ s pos ] <= "9"
THEN
n *:= 10 +:= ( ABS s[ s pos ] - ABS "0" )
FI
OD;
NOT valid
DO
print( ( "Invalid input, please enter an integer", newline ) )
OD;
n /= end value
DO
sum +:= n;
count +:= 1;
print( ( "New average: ", fixed( sum / count, -12, 4 ), newline ) )
OD
END
C
#include <stdio.h>
int main(int argc, char **argv)
{
// Unused variables
(void)argc;
(void)argv;
float currentAverage = 0;
unsigned int currentEntryNumber = 0;
for (;;)
{
int ret, entry;
printf("Enter rainfall int, 99999 to quit: ");
ret = scanf("%d", &entry);
if (ret)
{
if (entry == 99999)
{
printf("User requested quit.\n");
break;
}
else
{
currentEntryNumber++;
currentAverage = currentAverage + (1.0f/currentEntryNumber)*entry - (1.0f/currentEntryNumber)*currentAverage;
printf("New Average: %f\n", currentAverage);
}
}
else
{
printf("Invalid input\n");
while (getchar() != '\n'); // Clear input buffer before asking again
}
}
return 0;
}
C++
#include <iostream>
#include <limits>
int main()
{
float currentAverage = 0;
unsigned int currentEntryNumber = 0;
for (;;)
{
int entry;
std::cout << "Enter rainfall int, 99999 to quit: ";
std::cin >> entry;
if (!std::cin.fail())
{
if (entry == 99999)
{
std::cout << "User requested quit." << std::endl;
break;
}
else
{
currentEntryNumber++;
currentAverage = currentAverage + (1.0f/currentEntryNumber)*entry - (1.0f/currentEntryNumber)*currentAverage;
std::cout << "New Average: " << currentAverage << std::endl;
}
}
else
{
std::cout << "Invalid input" << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
return 0;
}
C#
namespace RosettaCode
{
class CSharpRecurringRainfall
{
static int ReadNextInput()
{
System.Console.Write("Enter rainfall int, 99999 to quit: ");
string input = System.Console.ReadLine();
if (System.Int32.TryParse(input, out int num))
{
return num;
}
else
{
System.Console.WriteLine("Invalid input");
return ReadNextInput();
}
}
static void Main()
{
double currentAverage = 0;
int currentEntryNumber = 0;
for (int lastInput = ReadNextInput(); lastInput != 99999; lastInput = ReadNextInput())
{
currentEntryNumber++;
currentAverage = currentAverage + (1.0/(float)currentEntryNumber)*lastInput - (1.0/(float)currentEntryNumber)*currentAverage;
System.Console.WriteLine("New Average: " + currentAverage);
}
}
}
}
D
import std.stdio;
void main()
{
float currentAverage = 0;
uint currentEntryNumber = 0;
for (;;)
{
int entry;
write("Enter rainfall int, 99999 to quit: ");
try {
readf("%d", entry);
readln();
}
catch (Exception e) {
writeln("Invalid input");
readln();
continue;
}
if (entry == 99999) {
writeln("User requested quit.");
break;
} else {
currentEntryNumber++;
currentAverage = currentAverage + (1.0/currentEntryNumber)*entry - (1.0/currentEntryNumber)*currentAverage;
writeln("New Average: ", currentAverage);
}
}
}
Fortran
Fortran 90
function getNextInput() result(Input)
implicit none
integer :: Input
integer :: Reason
Reason = 1
do while (Reason > 0)
print *, "Enter rainfall int, 99999 to quit: "
read (*,*,IOSTAT=Reason) Input
if (Reason > 0) then
print *, "Invalid input"
end if
enddo
end function getNextInput
program recurringrainfall
implicit none
real :: currentAverage
integer :: currentCount
integer :: lastInput
integer :: getNextInput
currentAverage = 0
currentCount = 0
do
lastInput = getNextInput()
if (lastInput == 99999) exit
currentCount = currentCount + 1
currentAverage = currentAverage + (1/real(currentCount))*lastInput - (1/real(currentCount))*currentAverage
print *, 'New Average: ', currentAverage
enddo
end program recurringrainfall
Java
class recurringrainfall
{
private static int GetNextInt()
{
while (true)
{
System.out.print("Enter rainfall int, 99999 to quit: ");
String input = System.console().readLine();
try
{
int n = Integer.parseInt(input);
return n;
}
catch (Exception e)
{
System.out.println("Invalid input");
}
}
}
private static void recurringRainfall() {
float currentAverage = 0;
int currentEntryNumber = 0;
while (true) {
int entry = GetNextInt();
if (entry == 99999)
return;
currentEntryNumber++;
currentAverage = currentAverage + ((float)1/currentEntryNumber)*entry - ((float)1/currentEntryNumber)*currentAverage;
System.out.println("New Average: " + currentAverage);
}
}
public static void main(String args[]) {
recurringRainfall();
}
}
Python
import sys
def get_next_input():
try:
num = int(input("Enter rainfall int, 99999 to quit: "))
except:
print("Invalid input")
return get_next_input()
return num
current_average = 0.0
current_count = 0
while True:
next = get_next_input()
if next == 99999:
sys.exit()
else:
current_count += 1
current_average = current_average + (1.0/current_count)*next - (1.0/current_count)*current_average
print("New average: ", current_average)
Rust
fn main() {
let mut current_average:f32 = 0.0;
let mut current_entry_number:u32 = 0;
loop
{
let current_entry;
println!("Enter rainfall int, 99999 to quit: ");
let mut input_text = String::new();
std::io::stdin().read_line(&mut input_text).expect("Failed to read from stdin");
let trimmed = input_text.trim();
match trimmed.parse::<u32>() {
Ok(new_entry) => current_entry = new_entry,
Err(..) => { println!("Invalid input"); continue; }
};
if current_entry == 99999
{
println!("User requested quit.");
break;
}
else
{
current_entry_number = current_entry_number + 1;
current_average = current_average + (1.0 / current_entry_number as f32)*(current_entry as f32) - (1.0 / current_entry_number as f32)*current_average;
println!("New Average: {}", current_average);
}
}
}
Wren
import "./ioutil" for Input
var n = 0
var sum = 0
while (true) {
var i = Input.integer("Enter integral rainfall (99999 to quit): ", 0)
if (i == 99999) break
n = n + 1
sum = sum + i
System.print(" The current average rainfall is %(sum/n)")
}