Insufficiently Advanced Technology

Mar 18 2012
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>

size_t check_malloc_size(void* p, size_t n);

int main(void) {
  void* p;
  unsigned n;
  for (;;) {
    if (scanf("%u", &n) != 1)
      break;
    p = malloc(n);
    printf("%u\n", (unsigned) check_malloc_size(p, n));
    free(p);
  }

  return 0;
}

size_t check_malloc_size(void* p, size_t n) {
  int fd[2];
  pid_t child;

  pipe(fd);
  child = fork();
  if (child == 0) {
    void* orig;
    void* dummy;
    dummy = malloc(1);

    for (orig = p; orig == p; p = realloc(p, ++n))
      ;

    free(dummy);
    write(fd[1], &n, sizeof(n));
    exit(EXIT_SUCCESS);
  } else {
    int status;
    read(fd[0], &n, sizeof(n));
    waitpid(child, &status, 0);
    return n - 1;
  }
  assert(0);
}

This is perfectly portable, idiomatic C code, right, guys.

Right.

Mar 16 2012
mapAndFoldl' mapF foldF foldAcc xs = go foldAcc xs
  where
    go a [] = ([], a)
    go a (x:xs) = let (ys, a') = (go $! foldF a x) xs
                  in  (mapF x : ys, a')

increaseAndSum = mapAndFoldl' succ (+) 0

n = 10000000

main = let (xs, s) = increaseAndSum [0..n]
       in  do print $ xs !! (n `div` 2)
              print s

I wish I could get this into constant space.

Feb 16 2012
    splitLine :: String -> Maybe (CIntPtr, CIntPtr, CIntPtr)
    splitLine (break (== '-') -> (fromHex -> Just start, break (== ' ') . tail -> (fromHex -> Just end, fromHex . takeWhile (/= ' ') . drop 6 -> Just offset))) = Just (start, end, offset)
    splitLine _ = Nothing

I might be doing this wrong.

Feb 12 2012

Reblog this if you want an anonymous commentary on your code quality

Feb 05 2012

Is it possible to dissect every singular digit from a sum and put them into an array?

i.e.:
if 101 * 101 = 10201
array = 1, 0, 2, 0 ,1

Whenever a question comes up like this I’m always tempted to provide an answer that appears to work if you just run it, but is obviously copy-pasted by someone who doesn’t understand how it works if they actually hand it in.

So, in the interest of posting code.

#include <iostream>

template<unsigned D>
struct digit;

template<unsigned N>
struct digits {
  digit<N%10> last_digit;
  digits<N/10> first_digits;
};

// match against all digits

template<>
struct digit<0> {
  char d;
  digit():d('0'){};
};

template<>
struct digit<1> {
  char d;
  digit():d('1'){};
};

template<>
struct digit<2> {
  char d;
  digit():d('2'){};
};

template<>
struct digit<3> {
  char d;
  digit():d('3'){};
};

template<>
struct digit<4> {
  char d;
  digit():d('4'){};
};

template<>
struct digit<5> {
  char d;
  digit():d('5'){};
};

template<>
struct digit<6> {
  char d;
  digit():d('6'){};
};

template<>
struct digit<7> {
  char d;
  digit():d('7'){};
};

template<>
struct digit<8> {
  char d;
  digit():d('8'){};
};

template<>
struct digit<9> {
  char d;
  digit():d('9'){};
};

template<>
struct digits<0> {
  char d;
  digits():d(0){};
};

int main() {
  digits<101*101> d;
  std::cout
    << "digits of 101*101: "
    << (char*)&d  // cast to char to print
    << std::endl;
}

Jan 07 2012

Enumerators are sooooo 2011, you guys.

import qualified Data.ByteString           as B
import           Network.HTTP.Conduit
import           Data.Conduit
import           Control.Monad
import           Control.Monad.IO.Class
import           Control.Exception.Lifted
import           Control.Concurrent.Lifted
import           Text.Printf

main = runResourceT $ do
    manager <- newManager
    sync <- newEmptyMVar

    forM_ ["http://reddit.com/r/haskell",
           "http://reddit.com/r/programming",
           "http://reddit.com/r/compsci",
           "http://reddit.com/r/coding"] $ \url -> fork $
        flip finally (putMVar sync ()) $ do
          req <- liftIO $ parseUrl url
          res <- http req manager
          responseBody res $$ sinkState url push close

    replicateM_ 4 $ takeMVar sync
  where
    push url input = do
      liftIO $ printf "Read %d bytes from %s\n" (B.length input) url
      return (url, Processing)
    close url = do
      liftIO $ printf "Finished with %s\n" url

16 notes

Dec 28 2011

Today I did not only mostly-finish a useless haskell program, I also got around to figuring out how to adjust the volume of bandcamp’s flash player. A productive day!

Oct 28 2011

So Haskell’s gloss package has a really cool web environment where you can edit and submit Haskell code in your browser hat defines a drawing or an animation or stuff! A bunch of people are hosting it at this site in order to teach a class on Haskell for kids.

It’s fairly fun to get from their almost-empty examples to silly little animations, which apparently get rendered on their server and streamed to the browser that displays them with a bunch of javascript. There’s also an engine for making small games, but it’s not really working too great over the web, this hangman example is not very responsive for me.

I think it’s a relatively exciting way to teach programming, sidestepping all the nerd bullshit and getting right to making shit show up on the screen. From what I can tell, the class is doing fine and they’re successful at getting the kids engaged with dry nerd stuff.

Oct 26 2011
import qualified Crypto.Hash.SHA1       as SHA1
import qualified Data.Enumerator        as E
import qualified Data.ByteString        as B
import qualified Data.ByteString.Lazy   as L
import qualified Data.Enumerator.Binary as EB


iter :: Monad m => E.Iteratee B.ByteString m [B.ByteString]
iter =
    nextChunk >>= hashChunks SHA1.init hashChunkSize
  where
    hashChunkSize = 16*1024*1024
    hashChunks :: Monad m => SHA1.Ctx -> Int -> Maybe B.ByteString -> E.Iteratee B.ByteString m [B.ByteString]
    hashChunks ctx remaining buf = case buf of
        Nothing -> if remaining == hashChunkSize
                     then return []
                     else let !hash = SHA1.finalize ctx in return [hash]
        Just chunk
          | B.null chunk -> nextChunk >>= hashChunks ctx remaining
          | B.length chunk < remaining -> nextChunk >>= hashChunks (SHA1.update ctx chunk) (remaining - B.length chunk)
          | otherwise -> let (before, after) = B.splitAt remaining chunk
                             !hash = (SHA1.finalize $ SHA1.update ctx before)
                         in (hash:) `fmap` hashChunks SHA1.init hashChunkSize (Just after)

iter2 :: Monad m => E.Iteratee B.ByteString m [B.ByteString]
iter2 = do
  chunk <- EB.take (16*1024*1024)
  if L.null chunk
    then return []
    else let !hash = SHA1.hashlazy chunk
         in  (hash :) `fmap` iter2

Can’t tell which disgusts me more.

.

11 notes

Oct 15 2011

It is that time again.

import qualified Data.Enumerator as E

enumerateeIter :: Monad m => E.Iteratee a m (Maybe b) -> E.Enumeratee a b m c
enumerateeIter iter step = do
  case step of
    E.Continue k -> do
      mb <- iter
      let stream = case mb of
                    Nothing -> E.EOF
                    Just b  -> E.Chunks [b]
      step' <- lift . E.runIteratee $ k stream
      enumerateeIter iter step'
    _            -> E.yield step E.EOF

3 notes

Page 1 of 3