Skip to content

Instantly share code, notes, and snippets.

@matthewhartstonge
Last active August 22, 2021 07:59
Show Gist options
  • Save matthewhartstonge/3eeb101a9b0a958889bd2ee254328d07 to your computer and use it in GitHub Desktop.
Save matthewhartstonge/3eeb101a9b0a958889bd2ee254328d07 to your computer and use it in GitHub Desktop.
Provides a functional and class based Dart solution for https://www.99-bottles-of-beer.net/
library ninetyninebottlesofbeer;
class Song {
// in Dart, underscore denotes private variables.
// Private variables are scoped to a library, so you can still access privates
// within a given file/library from other classes/functions.
// Note the above declared library name to limit the scope..
int _numBeers;
// The number of bottles of beers to sing from.
int bottlesOfBeer;
// Constructors in Dart can be defined using {} as syntactic sugar, exposing
// the local variable name as the parameter value, and auto-assignment, or
// you can us a more classic parameter based setter style declaration.
// This example uses both.
Song({this.bottlesOfBeer}) {
this._numBeers = this.bottlesOfBeer;
}
void reset() {
// In Dart, you don't have to specify `this.` to denote class level
// variables, but it certainly makes it clearer for developers between
// local and class level variables if you do.
_numBeers = bottlesOfBeer;
}
// sing uses a number of ternaries combined with string interpolation to print
// out our wonderful song.
void sing() {
String numBeers = this._numBeers.toString();
int newBeers = --this._numBeers;
if (this._numBeers == 0) {
numBeers = 'no more';
this.reset();
}
String oldBottles = numBeers == '1' ? 'bottle' : 'bottles';
String newBottles = newBeers == 1 ? 'bottle' : 'bottles';
String lastLine = numBeers != 'no more'
? 'take one down, pass it around, $newBeers $newBottles of beer on the wall.'
: 'Go to the store, buy some more, $newBeers bottles of beer on the wall.';
print('''
$numBeers $oldBottles of beer on the wall, $numBeers $oldBottles of beer.
$lastLine
''');
}
}
void main() {
int numberOfBeers = 99;
Song numberOfBeersOnTheWall = Song(bottlesOfBeer: numberOfBeers);
// Dart uses C-Style for looping.
for (int i = numberOfBeers; i >= 1; i--) {
numberOfBeersOnTheWall.sing();
}
}
// sing uses a number of ternaries combined with string interpolation to print
// out our wonderful song.
void sing(String numBeers, int newBeers) {
String oldBottles = numBeers == '1' ? 'bottle' : 'bottles';
String newBottles = newBeers == 1 ? 'bottle' : 'bottles';
String lastLine = numBeers != 'no more'
? 'take one down, pass it around, $newBeers $newBottles of beer on the wall.'
: 'Go to the store, buy some more, $newBeers bottles of beer on the wall.';
print('''
$numBeers $oldBottles of beer on the wall, $numBeers $oldBottles of beer.
$lastLine
''');
}
// Dart uses void main to define where an app starts executing.
void main() {
// In Dart, types are declared before the variable name.
int bottlesOfBeers = 99;
// Dart uses C-Style for looping.
for (int numBeers = bottlesOfBeers; numBeers >= 1;) {
// Dart supports pre-incrementing, for a reminder:
// ++i increments i and evaluates to the new value of i.
// i++ evaluates to the old value of i, and increments i.
sing(numBeers.toString(), --numBeers);
}
// We've reached our base case!
sing('no more', bottlesOfBeers);
}
@matthewhartstonge
Copy link
Author

matthewhartstonge commented Aug 22, 2021

For completeness, there are multiple accepted loop styles in Dart:

void main() {
  // For
  for (int i = 0; i < 10; i++) {
    print(i);
  }

  // For-In
  List<int> indices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  for (int index in indices) {
    print(index);
  }

  // While
  int i = 0;
  while (i < 10) {
    print(i);
    i++;
  }

  // Do-While
  i = 0;
  do {
    print(i);
    i++;
  } while (i < 10);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment