Skip to content

Instantly share code, notes, and snippets.

@lukewilson2002
Created July 30, 2018 17:20
Show Gist options
  • Save lukewilson2002/38b03236beb682ce549d40bd5a4aeeb0 to your computer and use it in GitHub Desktop.
Save lukewilson2002/38b03236beb682ce549d40bd5a4aeeb0 to your computer and use it in GitHub Desktop.
The same algorithm written in three different systems programming languages. You can use this to test compiler speeds, performances, generated assembly, or just for seeing the syntactical differences between the programs. Did this for fun, its not much really.
// This was actually the first implementation I wrote. I made
// this and decided I should try writing the same algorithm in
// Zig for learning the language. After I was done I found it
// interesting the differences in how they accomplish the same
// thing. I thought it'd be neat to write this algorithm in more
// languages just for science.
//
// The algorithm is very simple. Essentially you give it a string
// and it replaces every vowel with exclamation marks and returns
// the new one.
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
char *replace(const char *s)
{
char *out = _strdup(s);
for (char *c = out; *c != 0; c++)
switch (tolower(*c)) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
*c = '!';
break;
default:
break;
}
return out;
}
int main()
{
assert(strcmp(replace("aXeXiXoXu"), "!X!X!X!X!") == 0);
printf("It works :)\n");
return 0;
}
// The C++ implementation is very similar to the C one.
// The only things different are how it iterates through
// the string's characters using an iterator, and how we
// use std::string instead of C-strings.
//
// We actually still use `tolower` from `ctype.h`, and the
// assertion implementation from `assert.h` (or `cassert` in C++).
#include <string>
#include <cassert>
#include <iostream>
using namespace std;
string replace(const string s)
{
string out = s; // `std::string` implements automatic copying
for (string::iterator it = out.begin(); it != out.end(); it++)
switch (tolower(*it)) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
*it = '!';
break;
default:
break;
}
return out;
}
int main()
{
assert(replace("aXeXiXoXu") == "!X!X!X!X!");
cout << "It works :)" << endl;
return 0;
}
// We aren't working with pointers to strings at all, unlike C.
// Although, it is possible to use C-strings in Zig. We simply
// passed byte slices around. Slices are a little different from
// arrays. https://ziglang.org/documentation/master/#Slices
//
// This was actually my first time writing Zig code, so I'm sure
// its not very natively written and a little biased towards the C
// implementation since that's what I knew more. I'm sure there
// could have been a better way to pass strings than only using
// byte slices.
const std = @import("std");
const assert = std.debug.assert;
const mem = std.mem;
const allocator = std.debug.global_allocator;
// Since there wasn't a function like `strdup` in C, I just wrote an equivalent
fn strdup(src: []const u8) ![]u8 {
var newstring = try allocator.alloc(u8, src.len);
mem.copy(u8, newstring, src);
return newstring;
}
fn replace(s: []const u8) ![]u8
{
var out = try strdup(s);
defer allocator.free(out);
for (out) |*c| {
switch (c.*) {
'a','e','i','o','u' => c.* = '!',
else => {}
}
}
return out;
}
test "works"
{
const str = try replace("aXeXiXoXu"[0..]);
assert(mem.eql(u8, str, "!X!X!X!X!"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment