with Ada.Text_IO;
with Ada.Strings.Unbounded;

procedure Knapsack_01 is
   package US renames Ada.Strings.Unbounded;

   type Item is record
      Name   : US.Unbounded_String;
      Weight : Positive;
      Value  : Positive;
      Taken  : Boolean;
   end record;

   type Item_Array is array (Positive range <>) of Item;

   function Total_Weight (Items : Item_Array; Untaken : Boolean := False) return Natural is
      Sum : Natural := 0;
   begin
      for I in Items'Range loop
         if Untaken or else Items (I).Taken then
            Sum := Sum + Items (I).Weight;
         end if;
      end loop;
      return Sum;
   end Total_Weight;

   function Total_Value (Items : Item_Array; Untaken : Boolean := False) return Natural is
      Sum : Natural := 0;
   begin
      for I in Items'Range loop
         if Untaken or else Items (I).Taken then
            Sum := Sum + Items (I).Value;
         end if;
      end loop;
      return Sum;
   end Total_Value;

   function Max (Left, Right : Natural) return Natural is
   begin
      if Right > Left then
         return Right;
      else
         return Left;
      end if;
   end Max;

   procedure Solve_Knapsack_01 (Items : in out Item_Array;
                                Weight_Limit : Positive := 400) is
      type W_Array is array (0..Items'Length, 0..Weight_Limit) of Natural;
      W : W_Array := (others => (others => 0));
   begin
      -- fill W
      for I in Items'Range loop
         for J in 1 .. Weight_Limit loop
            if Items (I).Weight > J then
               W (I, J) := W (I - 1, J);
            else
               W (I, J) := Max (W (I - 1, J),
                                W (I - 1, J - Items (I).Weight) + Items (I).Value);
            end if;
         end loop;
      end loop;
      declare
         Rest : Natural := Weight_Limit;
      begin
         for I in reverse Items'Range loop
            if W (I, Rest) /= W (I - 1, Rest) then
               Items (I).Taken := True;
               Rest := Rest - Items (I).Weight;
            end if;
         end loop;
      end;
   end Solve_Knapsack_01;

   All_Items : Item_Array :=
     ( (US.To_Unbounded_String ("map"),                      9, 150, False),
       (US.To_Unbounded_String ("compass"),                 13,  35, False),
       (US.To_Unbounded_String ("water"),                  153, 200, False),
       (US.To_Unbounded_String ("sandwich"),                50, 160, False),
       (US.To_Unbounded_String ("glucose"),                 15,  60, False),
       (US.To_Unbounded_String ("tin"),                     68,  45, False),
       (US.To_Unbounded_String ("banana"),                  27,  60, False),
       (US.To_Unbounded_String ("apple"),                   39,  40, False),
       (US.To_Unbounded_String ("cheese"),                  23,  30, False),
       (US.To_Unbounded_String ("beer"),                    52,  10, False),
       (US.To_Unbounded_String ("suntan cream"),            11,  70, False),
       (US.To_Unbounded_String ("camera"),                  32,  30, False),
       (US.To_Unbounded_String ("t-shirt"),                 24,  15, False),
       (US.To_Unbounded_String ("trousers"),                48,  10, False),
       (US.To_Unbounded_String ("umbrella"),                73,  40, False),
       (US.To_Unbounded_String ("waterproof trousers"),     42,  70, False),
       (US.To_Unbounded_String ("waterproof overclothes"),  43,  75, False),
       (US.To_Unbounded_String ("note-case"),               22,  80, False),
       (US.To_Unbounded_String ("sunglasses"),               7,  20, False),
       (US.To_Unbounded_String ("towel"),                   18,  12, False),
       (US.To_Unbounded_String ("socks"),                    4,  50, False),
       (US.To_Unbounded_String ("book"),                    30,  10, False) );

begin
   Solve_Knapsack_01 (All_Items, 400);
   Ada.Text_IO.Put_Line ("Total Weight: " & Natural'Image (Total_Weight (All_Items)));
   Ada.Text_IO.Put_Line ("Total Value:  " & Natural'Image (Total_Value  (All_Items)));
   Ada.Text_IO.Put_Line ("Items:");
   for I in All_Items'Range loop
      if All_Items (I).Taken then
         Ada.Text_IO.Put_Line ("   " & US.To_String (All_Items (I).Name));
      end if;
   end loop;
end Knapsack_01;

The code determines the optimal combination of items a tourist can carry in his knapsack, given a maximum weight limit of 4kg (400 dag), such that the total value of the items is maximized. The items cannot be divided or diminished.


with Ada.Text_IO;  use Ada.Text_IO;

procedure Test_Short_Circuit is
   function A (Value : Boolean) return Boolean is
   begin
      Put (" A=" & Boolean'Image (Value));
      return Value;
   end A;
   function B (Value : Boolean) return Boolean is
   begin
      Put (" B=" & Boolean'Image (Value));
      return Value;
   end B;
begin
   for I in Boolean'Range loop
      for J in Boolean'Range loop
         Put (" (A and then B)=" & Boolean'Image (A (I) and then B (J)));
         New_Line;
      end loop;
   end loop;
   for I in Boolean'Range loop
      for J in Boolean'Range loop
         Put (" (A or else B)=" & Boolean'Image (A (I) or else B (J)));
         New_Line;
      end loop;
   end loop;
end Test_Short_Circuit;

Sample output:
 A=FALSE (A and then B)=FALSE
 A=FALSE (A and then B)=FALSE
 A=TRUE B=FALSE (A and then B)=FALSE
 A=TRUE B=TRUE (A and then B)=TRUE
 A=FALSE B=FALSE (A or else B)=FALSE
 A=FALSE B=TRUE (A or else B)=TRUE
 A=TRUE (A or else B)=TRUE
 A=TRUE (A or else B)=TRUE

The code creates two functions, 'a' and 'b', which accept and return the same boolean value, and print their name when called. The code then calculates the values of 'x' and 'y' using the 'and' and 'or' operators respectively, ensuring that function 'b' is only called when necessary. This is achieved through short-circuit evaluation, or if not supported, through nested 'if' statements. In the case of Ada, built-in short-circuit operations 'then' and 'or else' are used.


package Morse is

   type Symbols is (Nul, '-', '.', ' ');
   -- Nul is the letter separator, space the word separator;
   Dash : constant Symbols := '-';
   Dot : constant Symbols := '.';
   type Morse_Str is array (Positive range <>) of Symbols;
   pragma Pack (Morse_Str);

   function Convert (Input : String) return Morse_Str;
   procedure Morsebeep (Input : Morse_Str);

private
   subtype Reschars is Character range ' ' .. 'Z';
   -- restricted set of characters from 16#20# to 16#60#
   subtype Length is Natural range 1 .. 5;
   subtype Codes is Morse_Str (Length);
   -- using the current ITU standard with 5 signs
   -- only alphanumeric characters  are taken into consideration

   type Codings is record
      L : Length;
      Code : Codes;
   end record;
   Table : constant array (Reschars) of Codings :=
     ('A' => (2, ".-   "), 'B' => (4, "-... "),  'C' => (4, "-.-. "),
      'D' => (3, "-..  "), 'E' => (1, ".    "),  'F' => (4, "..-. "),
      'G' => (3, "--.  "), 'H' => (4, ".... "),  'I' => (2, "..   "),
      'J' => (4, ".--- "), 'K' => (3, "-.-  "),  'L' => (4, ".-.. "),
      'M' => (2, "--   "), 'N' => (2, "-.   "),  'O' => (3, "---  "),
      'P' => (4, ".--. "), 'Q' => (4, "--.- "),  'R' => (3, ".-.  "),
      'S' => (3, "...  "), 'T' => (1, "-    "),  'U' => (3, "..-  "),
      'V' => (4, "...- "), 'W' => (3, ".--  "),  'X' => (4, "-..- "),
      'Y' => (4, "-.-- "), 'Z' => (4, "--.. "),  '1' => (5, ".----"),
      '2' => (5, "..---"), '3' => (5, "...--"),  '4' => (5, "....-"),
      '5' => (5, "....."), '6' => (5, "-...."),  '7' => (5, "--..."),
      '8' => (5, "---.."), '9' => (5, "----."),  '0' => (5, "-----"),
      others => (1, "     ")); -- Dummy => Other characters do not need code.

end Morse;

with Ada.Strings.Maps, Ada.Characters.Handling, Interfaces.C;
use  Ada, Ada.Strings, Ada.Strings.Maps, Interfaces;

package body Morse is

   Dit, Dah, Lettergap, Wordgap : Duration; -- in seconds
   Dit_ms, Dah_ms : C.unsigned; -- durations expressed in ms
   Freq : constant C.unsigned := 1280; -- in Herz

   Morse_Sequence : constant Character_Sequence :=
      " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
   Morse_charset : constant Character_Set := To_Set (Morse_Sequence);

   function Convert (Input : String) return Morse_Str is
      Cap_String : constant String := Characters.Handling.To_Upper (Input);
      Result : Morse_Str (1 .. 7 * Input'Length); -- Upper Capacity
      First, Last : Natural := 0;
      Char_code : Codings;
   begin
      for I in Cap_String'Range loop
         if Is_In (Cap_String (I), Morse_charset) then
            First := Last + 1;
            if Cap_String (I) = ' ' then
               Result (First) := ' ';
               Last := Last + 1;
            else
               Char_code := Table (Reschars (Cap_String (I)));
               Last := First + Char_code.L - 1;
               Result (First .. Last) := Char_code.Code (1 .. Char_code.L);
               Last := Last + 1;
               Result (Last) := Nul;
            end if;
         end if;
      end loop;
      if Result (Last) /= ' ' then
         Last := Last + 1;
         Result (Last) := ' ';
      end if;
      return Result (1 .. Last);
   end Convert;

   procedure Morsebeep (Input : Morse_Str) is
      -- Beep is not portable : adapt to your OS/sound board
      -- Implementation for Windows XP / interface to fn in stdlib
      procedure win32xp_beep
        (dwFrequency : C.unsigned;
         dwDuration : C.unsigned);
      pragma Import (C, win32xp_beep, "_beep");
   begin
      for I in Input'Range loop
         case Input (I) is
            when Nul =>
               delay Lettergap;
            when Dot =>
               win32xp_beep (Freq, Dit_ms);
               delay Dit;
            when Dash =>
               win32xp_beep (Freq, Dah_ms);
               delay Dit;
            when ' ' =>
               delay Wordgap;
         end case;
      end loop;
   end Morsebeep;
begin
   Dit := 0.20;
   Lettergap := 2 * Dit;
   Dah := 3 * Dit;
   Wordgap := 4 * Dit;
   Dit_ms := C.unsigned (Integer (Dit * 1000));
   Dah_ms := C.unsigned (Integer (Dah * 1000));
end Morse;

with Morse;            use Morse;
procedure Morse_Tx is
begin
   Morsebeep (Convert ("Science sans Conscience"));
end Morse_Tx;

"Code outputs audible Morse code from a given string to an audio device, such as a PC speaker. It ignores unknown characters or indicates them with a different pitch. It is compatible with Ada95 and works on Windows 32 XP, but not on Vista due to the ineffectiveness of the Beep function."


Build with gnatchop abc.ada; gnatmake abc_problem

with Ada.Characters.Handling;
use Ada.Characters.Handling;

package Abc is
    type Block_Faces is array(1..2) of Character;
    type Block_List is array(positive range <>) of Block_Faces;
    function Can_Make_Word(W: String; Blocks: Block_List) return Boolean;
end Abc;

package body Abc is

function Can_Make_Word(W: String; Blocks: Block_List) return Boolean is
    Used : array(Blocks'Range) of Boolean := (Others => False);
    subtype wIndex is Integer range W'First..W'Last;
    wPos : wIndex;
begin
    if W'Length = 0 then
        return True;
    end if;
    wPos := W'First;
    while True loop
        declare
            C : Character := To_Upper(W(wPos));
            X : constant wIndex := wPos;
        begin
            for I in Blocks'Range loop
                if (not Used(I)) then
                    if C = To_Upper(Blocks(I)(1)) or C = To_Upper(Blocks(I)(2)) then
                        Used(I) := True;
                        if wPos = W'Last then
                            return True;
                        end if;
                        wPos := wIndex'Succ(wPos);
                        exit;
                    end if;
                end if;
            end loop;
            if X = wPos then
                return False;
            end if;
        end;
    end loop;
    return False;
end Can_Make_Word;

end Abc;

with Ada.Text_IO, Ada.Strings.Unbounded, Abc;
use Ada.Text_IO, Ada.Strings.Unbounded, Abc;

procedure Abc_Problem is
    Blocks : Block_List := (
          ('B','O'), ('X','K'), ('D','Q'), ('C','P')
        , ('N','A'), ('G','T'), ('R','E'), ('T','G')
        , ('Q','D'), ('F','S'), ('J','W'), ('H','U')
        , ('V','I'), ('A','N'), ('O','B'), ('E','R')
        , ('F','S'), ('L','Y'), ('P','C'), ('Z','M')
    );
    function "+" (S : String) return Unbounded_String renames To_Unbounded_String;
    words : array(positive range <>) of Unbounded_String := (
          +"A"
        , +"BARK"
        , +"BOOK"
        , +"TREAT"
        , +"COMMON"
        , +"SQUAD"
        , +"CONFUSE"
        -- Border cases:
        -- , +"CONFUSE2"
        -- , +""
    );
begin
    for I in words'Range loop
        Put_Line ( To_String(words(I)) & ": " & Boolean'Image(Can_Make_Word(To_String(words(I)),Blocks)) );
    end loop;
end Abc_Problem;

"Output: The code defines a function that checks if a given word can be spelled using a specific collection of ABC blocks. Each block contains two letters and can only be used once. The function is case-insensitive and returns a boolean value based on whether or not the word can be formed."


Works with: GNAT
with Ada.Text_IO; use Ada.Text_IO;
with GNAT.MD5;

procedure MD5_Digest is
begin
   Put(GNAT.MD5.Digest("Foo bar baz"));
end MD5_Digest;

implement an MD5 encoding for a given string. The codes also include an optional validation using test values from IETF RFC (1321) for MD5. However, due to known weaknesses of MD5, alternatives like SHA-256 or SHA-3 are recommended for production-grade cryptography. If the solution is a library, refer to MD5/Implementation for a scratch implementation.


Works with: Ada version 2012
with Ada.Containers.Generic_Array_Sort;
with Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;
with Ada.Unchecked_Deallocation;

procedure Sort_List_Identifiers is
   type Natural_Array is array (Positive range <>) of Natural;
   type Unbounded_String_Array is array(Positive range <>) of Unbounded_String;

   function To_Natural_Array(input : in String) return Natural_Array
   is
      target : Natural_Array(1 .. Ada.Strings.Fixed.Count(input, ".") + 1);
      from : Natural := input'First;
      to : Natural := Ada.Strings.Fixed.Index(input, ".");
      index : Positive := target'First;
   begin
      while to /= 0 loop
         target(index) := Natural'Value(input(from .. to - 1));
         from := to + 1;
         index := index + 1;
         to := Ada.Strings.Fixed.Index(input, ".", from);
      end loop;
      target(index) := Natural'Value(input(from .. input'Last));
      return target;
   end To_Natural_Array;

   function Lesser(Left, Right : in Unbounded_String) return Boolean is
   begin
      return To_Natural_Array(To_String(Left)) < To_Natural_Array(To_String(Right));
   end Lesser;

   procedure Sort is new Ada.Containers.Generic_Array_Sort
     (Index_Type   => Positive,
      Element_Type => Unbounded_String,
      Array_Type   => Unbounded_String_Array,
      "<"          => Lesser);

   table : Unbounded_String_Array :=
     (To_Unbounded_String("1.3.6.1.4.1.11.2.17.19.3.4.0.10"),
      To_Unbounded_String("1.3.6.1.4.1.11.2.17.5.2.0.79"),
      To_Unbounded_String("1.3.6.1.4.1.11.2.17.19.3.4.0.4"),
      To_Unbounded_String("1.3.6.1.4.1.11150.3.4.0.1"),
      To_Unbounded_String("1.3.6.1.4.1.11.2.17.19.3.4.0.1"),
      To_Unbounded_String("1.3.6.1.4.1.11150.3.4.0"));
begin
   Sort(table);
   for element of table loop
      Ada.Text_IO.Put_Line(To_String(element));
   end loop;
end Sort_List_Identifiers;

sort a list of Object Identifiers (OIDs) in their natural lexicographical order. The OIDs are strings of non-negative integers separated by dots.


Library: GNAT RTL
with GNAT.Sockets;  use GNAT.Sockets;

procedure Socket_Send is
   Client : Socket_Type;
begin
   Initialize;
   Create_Socket  (Socket => Client);
   Connect_Socket (Socket => Client,
                   Server => (Family => Family_Inet,
                              Addr   => Inet_Addr ("127.0.0.1"),
                              Port   => 256));
   String'Write (Stream (Client), "hello socket world");
   Close_Socket (Client);
end Socket_Send;

opens a socket to localhost on port 256, sends the message "hello socket world", and then closes the socket.


Library: AWS
with AWS.SMTP, AWS.SMTP.Client, AWS.SMTP.Authentication.Plain;
with Ada.Text_IO;
use  Ada, AWS;

procedure Sendmail is
   Status : SMTP.Status;
   Auth : aliased constant SMTP.Authentication.Plain.Credential :=
      SMTP.Authentication.Plain.Initialize ("id", "password");
   Isp : SMTP.Receiver;
begin
   Isp :=
      SMTP.Client.Initialize
        ("smtp.mail.com",
         Port       => 5025,
         Credential => Auth'Unchecked_Access);
   SMTP.Client.Send
     (Isp,
      From    => SMTP.E_Mail ("Me", "me@some.org"),
      To      => SMTP.E_Mail ("You", "you@any.org"),
      Subject => "subject",
      Message => "Here is the text",
      Status  => Status);
   if not SMTP.Is_Ok (Status) then
      Text_IO.Put_Line
        ("Can't send message :" & SMTP.Status_Message (Status));
   end if;
end Sendmail;

Implement a function to send an email with parameters for From, To, Cc addresses, Subject, message text, and optional server name and login details. The code also provides notifications for any issues or success, and uses libraries or external programs for execution. It ensures portability across different operating systems. Sensitive data used in examples is obfuscated.


with Ada.Text_IO;

procedure Octal is
   package IIO is new Ada.Text_IO.Integer_IO(Integer);
begin
   for I in 0 .. Integer'Last loop
      IIO.Put(I, Base => 8);
      Ada.Text_IO.New_Line;
   end loop;
end Octal;

       8#0#
       8#1#
       8#2#
       8#3#
       8#4#
       8#5#
       8#6#
       8#7#
      8#10#
      8#11#
      8#12#
      8#13#
      8#14#
      8#15#
      8#16#
      8#17#
      8#20#

"Generate a sequential count in octal format starting from zero, incrementing by one, each number appearing on a single line, until the program is terminated or the maximum numeric value is reached."


generic
   type Swap_Type is private; -- Generic parameter
procedure Generic_Swap (Left, Right : in out Swap_Type);

procedure Generic_Swap (Left, Right : in out Swap_Type) is
   Temp : constant Swap_Type := Left;
begin
   Left := Right;
   Right := Temp;
end Generic_Swap;

usage[edit]

with Generic_Swap;
...
type T is ...
procedure T_Swap is new Generic_Swap (Swap_Type => T);
A, B : T;
...
T_Swap (A, B);

implement a generic swap function that can interchange the values of two variables or storage places, regardless of their types. The function is designed to work with both statically and dynamically typed languages, with some constraints for compatibility in typed languages. The function also addresses challenges in generic programming, parametric polymorphism, and destructive operations in functional languages. In Ada, the generic parameters are defined in a procedure specification and the algorithm in a procedure body. The procedure needs to be instantiated for each intended use type.


function Palindrome (Text : String) return Boolean is
begin
   for Offset in 0..Text'Length / 2 - 1 loop
      if Text (Text'First + Offset) /= Text (Text'Last - Offset) then
         return False;
      end if;
   end loop;
   return True;
end Palindrome;

function Palindrome (Text : String) return Boolean is
(for all i in Text'Range => Text(i)= Text(Text'Last-i+Text'First));

The code checks if a given sequence of characters is a palindrome. It supports Unicode characters and also detects inexact palindromes by ignoring white-space, punctuation, and case. It uses a function to reverse a string for the task.


with Ada.Environment_Variables; use Ada.Environment_Variables;
with Ada.Text_Io; use Ada.Text_Io;

procedure Print_Path is
begin
   Put_Line("Path : " & Value("PATH"));
end Print_Path;

with Ada.Environment_Variables; use Ada.Environment_Variables;
with Ada.Text_Io; use Ada.Text_Io;

procedure Env_Vars is
   procedure Print_Vars(Name, Value : in String) is
   begin
      Put_Line(Name & " : " & Value);
   end Print_Vars;
begin
   Iterate(Print_Vars'access);
end Env_Vars;

Alternative version using Matreshka[edit]

with Ada.Wide_Wide_Text_IO;

with League.Application;
with League.Strings;

procedure Main is

   function "+"
    (Item : Wide_Wide_String) return League.Strings.Universal_String
       renames League.Strings.To_Universal_String;

begin
   Ada.Wide_Wide_Text_IO.Put_Line
    (League.Application.Environment.Value (+"HOME").To_Wide_Wide_String);
end Main;

demonstrate how to retrieve a specific environment variable and print all environment variables using Matreshka in a Unix system.


Translation of: Javascript
with Ada.Text_IO; use Ada.Text_IO;

procedure Sudan_Function is

   function F (N, X, Y : Natural) return Natural
   is (if    N = 0 then X + Y
       elsif Y = 0 then X
       else  F (N => N - 1,
                X => F (N, X, Y - 1),
                Y => F (N, X, Y - 1) + Y));

begin
   Put_Line ("F0 (0, 0) = " & F (0, 0, 0)'Image);
   Put_Line ("F1 (1, 1) = " & F (1, 1, 1)'Image);
   Put_Line ("F1 (3, 3) = " & F (1, 3, 3)'Image);
   Put_Line ("F2 (1, 1) = " & F (2, 1, 1)'Image);
   Put_Line ("F2 (2, 1) = " & F (2, 2, 1)'Image);
   Put_Line ("F3 (1, 1) = " & F (3, 1, 1)'Image);
end Sudan_Function;

Implement the Sudan function, a non-primitive recursive function. The function takes two arguments, x and y, and returns a value based on the defined recursive rules.


NSMutableArray *stack = [NSMutableArray array]; // creating

[stack addObject:value]; // pushing

id value = [stack lastObject];
[stack removeLastObject]; // popping

[stack count] == 0 // is empty?

implement a stack data structure with basic operations such as push, pop, and empty. The stack follows a last in, first out (LIFO) access policy and allows access to the topmost element without modifying the stack. It is used for resource management, particularly memory, in programming and is common in processors. The stack can also be used for implementing local variables of a recursive subprogram and is used in various algorithms in pattern matching, compiler construction, and machine learning. The stack is implemented using a NSMutableArray.


Recursive[edit]
-(long)fibonacci:(int)position
{
    long result = 0;
    if (position < 2) {
        result = position;
    } else {
        result = [self fibonacci:(position -1)] + [self fibonacci:(position -2)];
    }
    return result;
}
Iterative[edit]
+(long)fibonacci:(int)index {
    long beforeLast = 0, last = 1;
    while (index > 0) {
        last += beforeLast;
        beforeLast = last - beforeLast;
        --index;
    }
    return last;
}

generate the nth Fibonacci number, using either an iterative or recursive approach. The function also has an optional feature to support negative Fibonacci sequences.


Works with: Cocoa version Mac OS X 10.6+
NSArray *numbers = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],
                                             [NSNumber numberWithInt:2],
                                             [NSNumber numberWithInt:3],
                                             [NSNumber numberWithInt:4],
                                             [NSNumber numberWithInt:5], nil];
NSArray *evens = [numbers objectsAtIndexes:[numbers indexesOfObjectsPassingTest:
  ^BOOL(id obj, NSUInteger idx, BOOL *stop) { return [obj intValue] % 2 == 0; } ]];

Works with: Cocoa version Mac OS X 10.5+
NSArray *numbers = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],
                                             [NSNumber numberWithInt:2],
                                             [NSNumber numberWithInt:3],
                                             [NSNumber numberWithInt:4],
                                             [NSNumber numberWithInt:5], nil];
NSPredicate *isEven = [NSPredicate predicateWithFormat:@"modulus:by:(SELF, 2) == 0"];
NSArray *evens = [numbers filteredArrayUsingPredicate:isEven];
Works with: GNUstep
#import <Foundation/Foundation.h>

@interface NSNumber ( ExtFunc )
-(int) modulo2;
@end

@implementation NSNumber ( ExtFunc )
-(int) modulo2
{
  return [self intValue] % 2;
}
@end

int main()
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  NSArray *numbers = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],
                                               [NSNumber numberWithInt:2],
                                               [NSNumber numberWithInt:3],
                                               [NSNumber numberWithInt:4],
                                               [NSNumber numberWithInt:5], nil];

  NSPredicate *isEven = [NSPredicate predicateWithFormat:@"modulo2 == 0"];
  NSArray *evens = [numbers filteredArrayUsingPredicate:isEven];

  NSLog(@"%@", evens);

  [pool release];
  return 0;
}

select certain elements from an array into a new array in a generic way. Specifically, it selects all even numbers from an array. Optionally, it can also filter destructively by modifying the original array instead of creating a new one.


#import <Foundation/Foundation.h>

@interface NSString (Extended)
-(NSString *)reverseString;
@end

@implementation NSString (Extended)
-(NSString *) reverseString
{
    NSUInteger len = [self length];
    NSMutableString *rtr=[NSMutableString stringWithCapacity:len];
    //        unichar buf[1];

    while (len > (NSUInteger)0) {
        unichar uch = [self characterAtIndex:--len];
        [rtr appendString:[NSString stringWithCharacters:&uch length:1]];
    }
    return rtr;
}
@end

int main()
{
    @autoreleasepool {

        NSString *test = [@"!A string to be reverted!" reverseString];

        NSLog(@"%@", test);

    }
    return 0;
}
Supporting combining characters[edit]

#import <Foundation/Foundation.h>

@interface NSString (Extended)
-(NSString *)reverseString;
@end

@implementation NSString (Extended)
-(NSString *)reverseString
{
	NSInteger l = [self length] - 1;
	NSMutableString *ostr = [NSMutableString stringWithCapacity:[self length]];
	while (l >= 0)
	{
		NSRange range = [self rangeOfComposedCharacterSequenceAtIndex:l];
		[ostr appendString:[self substringWithRange:range]];
		l -= range.length;
	}
	return ostr;
}
@end

int main()
{
    @autoreleasepool {

        NSString *test = [@"as⃝df̅" reverseString];

        NSLog(@"%@", test);

    }
    return 0;
}

"Implements a function to reverse a given string, while preserving Unicode combining characters. For instance, it transforms "asdf" into "fdsa" and "as⃝df̅" into "f̅ds⃝a". This function extends the NSString object with a reverseString class method."


Translation of: Java

This example is incomplete. It is missing an @interface for AVLTree and also missing any @interface or @implementation for AVLTreeNode. Please ensure that it meets all task requirements and remove this message.

@implementation AVLTree

-(BOOL)insertWithKey:(NSInteger)key {

    if (self.root == nil) {
        self.root = [[AVLTreeNode alloc]initWithKey:key andParent:nil];
    } else {

        AVLTreeNode *n = self.root;
        AVLTreeNode *parent;

        while (true) {

            if (n.key == key) {
                return false;
            }

            parent = n;

            BOOL goLeft = n.key > key;
            n = goLeft ? n.left : n.right;

            if (n == nil) {

                if (goLeft) {
                    parent.left = [[AVLTreeNode alloc]initWithKey:key andParent:parent];
                } else {
                    parent.right = [[AVLTreeNode alloc]initWithKey:key andParent:parent];
                }
                [self rebalanceStartingAtNode:parent];
                break;
            }
        }
    }

    return true;
}

-(void)rebalanceStartingAtNode:(AVLTreeNode*)n {

    [self setBalance:@[n]];

    if (n.balance == -2) {
        if ([self height:(n.left.left)] >= [self height:n.left.right]) {
            n = [self rotateRight:n];
        } else {
            n = [self rotateLeftThenRight:n];
        }
    } else if (n.balance == 2) {
        if ([self height:n.right.right] >= [self height:n.right.left]) {
            n = [self rotateLeft:n];
        } else {
            n = [self rotateRightThenLeft:n];
        }
    }

    if (n.parent != nil) {
        [self rebalanceStartingAtNode:n.parent];
    } else {
        self.root = n;
    }
}

-(AVLTreeNode*)rotateRight:(AVLTreeNode*)a {

    AVLTreeNode *b = a.left;
    b.parent = a.parent;

    a.left = b.right;

    if (a.left != nil) {
        a.left.parent = a;
    }

    b.right = a;
    a.parent = b;

    if (b.parent != nil) {
        if (b.parent.right == a) {
            b.parent.right = b;
        } else {
            b.parent.left = b;
        }
    }

    [self setBalance:@[a,b]];
    return b;

}

-(AVLTreeNode*)rotateLeftThenRight:(AVLTreeNode*)n {

    n.left = [self rotateLeft:n.left];
    return [self rotateRight:n];

}

-(AVLTreeNode*)rotateRightThenLeft:(AVLTreeNode*)n {

    n.right = [self rotateRight:n.right];
    return [self rotateLeft:n];
}

-(AVLTreeNode*)rotateLeft:(AVLTreeNode*)a {

    //set a's right node as b
    AVLTreeNode* b = a.right;
    //set b's parent as a's parent (which could be nil)
    b.parent = a.parent;
    //in case b had a left child transfer it to a
    a.right = b.left;

    // after changing a's reference to the right child, make sure the parent is set too
    if (a.right != nil) {
        a.right.parent = a;
    }

    // switch a over to the left to be b's left child
    b.left = a;
    a.parent = b;

    if (b.parent != nil) {
        if (b.parent.right == a) {
            b.parent.right = b;
        } else {
            b.parent.right = b;
        }
    }

    [self setBalance:@[a,b]];

    return b;

}

-(void) setBalance:(NSArray*)nodesArray {

    for (AVLTreeNode* n in nodesArray) {

        n.balance = [self height:n.right] - [self height:n.left];
    }

}

-(int)height:(AVLTreeNode*)n {

    if (n == nil) {
        return -1;
    }

    return 1 + MAX([self height:n.left], [self height:n.right]);
}

-(void)printKey:(AVLTreeNode*)n {
    if (n != nil) {
        [self printKey:n.left];
        NSLog(@"%ld", n.key);
        [self printKey:n.right];
    }
}

-(void)printBalance:(AVLTreeNode*)n {
    if (n != nil) {
        [self printBalance:n.left];
        NSLog(@"%ld", n.balance);
        [self printBalance:n.right];
    }
}
@end
-- test

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        AVLTree *tree = [AVLTree new];
        NSLog(@"inserting values 1 to 6");
        [tree insertWithKey:1];
        [tree insertWithKey:2];
        [tree insertWithKey:3];
        [tree insertWithKey:4];
        [tree insertWithKey:5];
        [tree insertWithKey:6];

        NSLog(@"printing balance: ");
        [tree printBalance:tree.root];

        NSLog(@"printing key: ");
        [tree printKey:tree.root];
    }
    return 0;
}

implement an AVL tree, a self-balancing binary search tree where the heights of the two child subtrees of any node differ by at most one. The code ensures this by rebalancing the tree after each insertion or deletion. The operations of lookup, insertion, and deletion all take O(log n) time. The code does not allow duplicate node keys. The AVL tree implemented can be compared with red-black trees for its efficiency in lookup-intensive applications.


#import <Foundation/Foundation.h>

int main (int argc, const char *argv[]) {
  @autoreleasepool {

    NSSet *s1 = [NSSet setWithObjects:@"a", @"b", @"c", @"d", @"e", nil];
    NSSet *s2 = [NSSet setWithObjects:@"b", @"c", @"d", @"e", @"f", @"h", nil];
    NSSet *s3 = [NSSet setWithObjects:@"b", @"c", @"d", nil];
    NSSet *s4 = [NSSet setWithObjects:@"b", @"c", @"d", nil];
    NSLog(@"s1: %@", s1);
    NSLog(@"s2: %@", s2);
    NSLog(@"s3: %@", s3);
    NSLog(@"s4: %@", s4);

    // Membership
    NSLog(@"b in s1: %d", [s1 containsObject:@"b"]);
    NSLog(@"f in s1: %d", [s1 containsObject:@"f"]);

    // Union
    NSMutableSet *s12 = [NSMutableSet setWithSet:s1];
    [s12 unionSet:s2];
    NSLog(@"s1 union s2: %@", s12);

    // Intersection
    NSMutableSet *s1i2 = [NSMutableSet setWithSet:s1];
    [s1i2 intersectSet:s2];
    NSLog(@"s1 intersect s2: %@", s1i2);

    // Difference
    NSMutableSet *s1_2 = [NSMutableSet setWithSet:s1];
    [s1_2 minusSet:s2];
    NSLog(@"s1 - s2: %@", s1_2);

    // Subset of
    NSLog(@"s3 subset of s1: %d", [s3 isSubsetOfSet:s1]);

    // Equality
    NSLog(@"s3 = s4: %d", [s3 isEqualToSet:s4]);

    // Cardinality
    NSLog(@"size of s1: %lu", [s1 count]);

    // Has intersection (not disjoint)
    NSLog(@"does s1 intersect s2? %d", [s1 intersectsSet:s2]);

    // Adding and removing elements from a mutable set
    NSMutableSet *mut_s1 = [NSMutableSet setWithSet:s1];
    [mut_s1 addObject:@"g"];
    NSLog(@"mut_s1 after adding g: %@", mut_s1);
    [mut_s1 addObject:@"b"];
    NSLog(@"mut_s1 after adding b again: %@", mut_s1);
    [mut_s1 removeObject:@"c"];
    NSLog(@"mut_s1 after removing c: %@", mut_s1);

  }
  return 0;
}

demonstrate various set operations such as creation, checking if an element is present in a set, union, intersection, difference, subset and equality of sets. The code also optionally shows other set operations and methods to modify a mutable set. It may implement a set using an associative array, binary search tree, hash table, or an ordered array of binary bits. The code also discusses the time complexity of the basic test operation in different scenarios.


Works with: GNUstep
Works with: Cocoa
#import <Foundation/Foundation.h>

int main()
{
   @autoreleasepool {
      for(NSUInteger i=2008; i<2121; i++)
      {
         NSCalendarDate *d = [[NSCalendarDate alloc]
                              initWithYear: i
                              month: 12
                              day: 25
                              hour: 0 minute: 0 second:0
                              timeZone: [NSTimeZone timeZoneWithAbbreviation:@"CET"] ];
         if ( [d dayOfWeek] == 0 )
         {
            printf("25 Dec %u is Sunday\n", i);
         }
      }

   }
   return 0;
}

The code determines the years between 2008 and 2121 where Christmas (25th December) falls on a Sunday, using standard date handling libraries. It also compares the results with other languages to identify any anomalies in date/time representation, such as overflow issues similar to y2k problems.


NSArray *items = [NSArray arrayWithObjects:@"A", @"B", @"C", @"B", @"A", nil];

NSSet *unique = [NSSet setWithArray:items];

implement three methods to remove duplicate elements from an array: 1) Using a hash table, 2) Sorting the array and removing consecutive duplicates, and 3) Iterating through the list and discarding any repeated elements.


void quicksortInPlace(NSMutableArray *array, NSInteger first, NSInteger last, NSComparator comparator) {
    if (first >= last) return;
    id pivot = array[(first + last) / 2];
    NSInteger left = first;
    NSInteger right = last;
    while (left <= right) {
        while (comparator(array[left], pivot) == NSOrderedAscending)
            left++;
        while (comparator(array[right], pivot) == NSOrderedDescending)
            right--;
        if (left <= right)
            [array exchangeObjectAtIndex:left++ withObjectAtIndex:right--];
    }
    quicksortInPlace(array, first, right, comparator);
    quicksortInPlace(array, left, last, comparator);
}

NSArray* quicksort(NSArray *unsorted, NSComparator comparator) {
    NSMutableArray *a = [NSMutableArray arrayWithArray:unsorted];
    quicksortInPlace(a, 0, a.count - 1, comparator);
    return a;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray *a = @[ @1, @3, @5, @7, @9, @8, @6, @4, @2 ];
        NSLog(@"Unsorted: %@", a);
        NSLog(@"Sorted: %@", quicksort(a, ^(id x, id y) { return [x compare:y]; }));
        NSArray *b = @[ @"Emil", @"Peg", @"Helen", @"Juergen", @"David", @"Rick", @"Barb", @"Mike", @"Tom" ];
        NSLog(@"Unsorted: %@", b);
        NSLog(@"Sorted: %@", quicksort(b, ^(id x, id y) { return [x compare:y]; }));
    }
    return 0;
}

implement the Quicksort algorithm to sort an array or list of elements. The algorithm works by selecting a pivot element from the array and partitioning the other elements into two sub-arrays, according to whether they are less than or greater than the pivot. The sub-arrays are then recursively sorted. The codes also include an optimized version of Quicksort that works in place by swapping elements within the array to avoid memory allocation of more arrays. The pivot element selection method is not specified and can vary. The codes assume the latest XCode compiler with ARC enabled.


NSLog(@"%@", [NSDate date]);
NSLog(@"%@", [[NSDate date] descriptionWithCalendarFormat:@"%Y-%m-%d" timeZone:nil locale:nil]);
NSLog(@"%@", [[NSDate date] descriptionWithCalendarFormat:@"%A, %B %d, %Y" timeZone:nil locale:nil]);

Works with: Mac OS X version 10.4+
Works with: iOS
NSLog(@"%@", [NSDate date]);
NSDateFormatter *dateFormatter = [[NSDateFormat alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSLog(@"%@", [dateFormatter stringFromDate:[NSDate date]]);
[dateFormatter setDateFormat:@"EEEE, MMMM d, yyyy"];
NSLog(@"%@", [dateFormatter stringFromDate:[NSDate date]]);

display the current date in two formats: "2007-11-23" and "Friday, November 23, 2007".


#import <Foundation/Foundation.h>

+ (NSArray *)powerSetForArray:(NSArray *)array {
	UInt32 subsetCount = 1 << array.count;
	NSMutableArray *subsets = [NSMutableArray arrayWithCapacity:subsetCount];
	for(int subsetIndex = 0; subsetIndex < subsetCount; subsetIndex++) {
		NSMutableArray *subset = [[NSMutableArray alloc] init];
		for (int itemIndex = 0; itemIndex < array.count; itemIndex++) {
			if((subsetIndex >> itemIndex) & 0x1) {
				[subset addObject:array[itemIndex]];
			}
		}
		[subsets addObject:subset];
	}
	return subsets;
}

implement a function that takes a set as input and returns its power set. The power set includes all subsets of the input set, including the empty set and the set itself. The function also demonstrates the handling of edge cases where the input set is empty or contains only the empty set.


// NSArrays are ordered collections of NSObject subclasses only.

// Create an array of NSString objects.
NSArray *firstArray = [[NSArray alloc] initWithObjects:@"Hewey", @"Louie", @"Dewey", nil];

// NSArrays are immutable; it does have a mutable subclass, however - NSMutableArray.
// Let's instantiate one with a mutable copy of our array.
// We can do this by sending our first array a -mutableCopy message.
NSMutableArray *secondArray = [firstArray mutableCopy];

// Replace Louie with Launchpad McQuack.
[secondArray replaceObjectAtIndex:1 withObject:@"Launchpad"];

// Display the first object in the array.
NSLog(@"%@", [secondArray objectAtIndex:0]);

// In non-ARC or non-GC environments, retained objects must be released later.
[firstArray release];
[secondArray release];

// There is also a modern syntax which allows convenient creation of autoreleased immutable arrays.
// No nil termination is then needed.
NSArray *thirdArray = @[ @"Hewey", @"Louie", @"Dewey", @1, @2, @3 ];

demonstrate the basic syntax of arrays in the specific programming language, including creating an array, assigning a value to it, and retrieving an element. It also showcases the use of both fixed-length and dynamic arrays, and includes the functionality of pushing a value into the array.


[[NSFileManager defaultManager] copyItemAtPath:@"input.txt" toPath:@"output.txt" error:NULL];

NSData *data = [NSData dataWithContentsOfFile:@"input.txt"];

[data writeToFile:@"output.txt" atomically:YES];

demonstrate how to create a file named "output.txt" and populate it with the contents of "input.txt" using an intermediate variable. The process involves reading from a file into a variable and then writing the variable's contents into another file. It also includes a method for copying files using NSFileManager. The code is designed to write the content to a temporary file first, then rename the temporary file to the destination file, replacing the existing file. Error checking and failure handling are also considered in the code.


Works with: GNUstep
Works with: Cocoa
NSLog(@"%@", @"alphaBETA".uppercaseString);
NSLog(@"%@", @"alphaBETA".lowercaseString);

NSLog(@"%@", @"foO BAr".capitalizedString); // "Foo Bar"

demonstrate the conversion of the string "alphaBETA" to upper-case and lower-case using the default string literal or ASCII encoding. The code also showcases additional case conversion functions such as swapping case or capitalizing the first letter if available in the language's library. Note that in some languages, the toLower and toUpper functions may not be reversible.


The code provides two functions to solve the Closest Pair of Points problem in a planar case. The first function uses a brute-force algorithm with a time complexity of O(n^2) to find the closest pair of points in a given set. The second function uses a recursive divide and conquer approach with a time complexity of O(n log n) to find the closest pair of points in a set sorted by x and y coordinates.


a set: a collection of unique elements (like mathematical set). Possible operations on a set are not shown;
a counted set (also known as bag): each elements have a counter that says how many time that element appears;
a dictionary: pairs key-value.

#import <Foundation/Foundation.h>

void show_collection(id coll)
{
  for ( id el in coll )
  {
    if ( [coll isKindOfClass: [NSCountedSet class]] ) {
      NSLog(@"%@ appears %lu times", el, [coll countForObject: el]);
    } else if ( [coll isKindOfClass: [NSDictionary class]] ) {
      NSLog(@"%@ -> %@", el, coll[el]);
    } else {
      NSLog(@"%@", el);
    }
  }
  printf("\n");
}

int main()
{
  @autoreleasepool {

    // create an empty set
    NSMutableSet *set = [[NSMutableSet alloc] init];
    // populate it
    [set addObject: @"one"];
    [set addObject: @10];
    [set addObjectsFromArray: @[@"one", @20, @10, @"two"] ];
    // let's show it
    show_collection(set);

    // create an empty counted set (a bag)
    NSCountedSet *cset = [[NSCountedSet alloc] init];
    // populate it
    [cset addObject: @"one"];
    [cset addObject: @"one"];
    [cset addObject: @"two"];
    // show it
    show_collection(cset);

    // create a dictionary
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    // populate it
    dict[@"four"] = @4;
    dict[@"eight"] = @8;
    // show it
    show_collection(dict);

  }
  return EXIT_SUCCESS;
}

The code creates a collection in a statically-typed language, adds a few values of a common data type to it, and reviews the programming examples to ensure they meet the task requirements. It also explores different collection classes in OpenStep, GNUstep, and Cocoa, excluding arrays indexed by an integer.


[@"abcd" hasPrefix:@"ab"] //returns true
[@"abcd" hasSuffix:@"zn"] //returns false
int loc = [@"abab" rangeOfString:@"bb"].location //returns -1
loc = [@"abab" rangeOfString:@"ab"].location //returns 0
loc = [@"abab" rangeOfString:@"ab" options:0 range:NSMakeRange(loc+1, [@"abab" length]-(loc+1))].location //returns 2

The code checks if a given string starts with, contains, or ends with a second string. It also prints the location of the match and handles multiple occurrences of the second string within the first string.


Works with: GNUstep
Works with: Cocoa

#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>

@interface Win : NSWindow
{
}
- (void)applicationDidFinishLaunching: (NSNotification *)notification;
- (BOOL)applicationShouldTerminateAfterLastWindowClosed: (NSNotification *)notification;
@end

@implementation Win : NSWindow
-(instancetype) init
{
  if ((self = [super
    initWithContentRect: NSMakeRect(0, 0, 800, 600)
    styleMask: (NSTitledWindowMask | NSClosableWindowMask)
    backing: NSBackingStoreBuffered
    defer: NO])) {

    [self setTitle: @"A Window"];
    [self center];
  }
  return self;
}

- (void)applicationDidFinishLaunching: (NSNotification *)notification
{
  [self orderFront: self];
}

- (BOOL)applicationShouldTerminateAfterLastWindowClosed: (NSNotification *)notification
{
  return YES;
}
@end

int main()
{
  @autoreleasepool {

    [NSApplication sharedApplication];
    Win *mywin = [[Win alloc] init];
    [NSApp setDelegate: mywin];
    [NSApp runModalForWindow: mywin];

  }
  return EXIT_SUCCESS;
}

create and display an empty 800x600 GUI window titled "A Window", centered on the screen, and respond to close requests.


#import <Foundation/Foundation.h>

int main (int argc, const char *argv[]) {
  @autoreleasepool {

    NSData *data = [NSData dataWithContentsOfFile:@(argv[1])];
    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSCountedSet *countedSet = [[NSCountedSet alloc] init];
    NSUInteger len = [string length];
    for (NSUInteger i = 0; i < len; i++) {
      unichar c = [string characterAtIndex:i];
      if ([[NSCharacterSet letterCharacterSet] characterIsMember:c])
        [countedSet addObject:@(c)];
    }
    for (NSNumber *chr in countedSet) {
      NSLog(@"%C => %lu", (unichar)[chr integerValue], [countedSet countForObject:chr]);
    }

  }
  return 0;
}

Open a text file, count the frequency of each letter, and differentiate between counting all characters or only letters A to Z.


#import <Foundation/Foundation.h>

@interface RCListElement<T> : NSObject
{
  RCListElement<T> *next;
  T datum;
}
- (RCListElement<T> *)next;
- (T)datum;
- (RCListElement<T> *)setNext: (RCListElement<T> *)nx;
- (void)setDatum: (T)d;
@end

@implementation RCListElement
- (RCListElement *)next
{
  return next;
}
- (id)datum
{
  return datum;
}
- (RCListElement *)setNext: (RCListElement *)nx
{
  RCListElement *p = next;
  next = nx;
  return p;
}
- (void)setDatum: (id)d
{
  datum = d;
}
@end

define a data structure for a singly-linked list element. This element contains a data member for storing a numeric value and a mutable link to the next element in the list.


@interface Pair : NSObject {
    NSString *name;
    NSString *value;
}
+(instancetype)pairWithName:(NSString *)n value:(NSString *)v;
-(instancetype)initWithName:(NSString *)n value:(NSString *)v;
-(NSString *)name;
-(NSString *)value;
@end

@implementation Pair
+(instancetype)pairWithName:(NSString *)n value:(NSString *)v {
    return [[self alloc] initWithName:n value:v];
}
-(instancetype)initWithName:(NSString *)n value:(NSString *)v {
    if ((self = [super init])) {
        name = n;
        value = v;
    }
    return self;
}
-(NSString *)name { return name; }
-(NSString *)value { return value; }
-(NSString *)description {
    return [NSString stringWithFormat:@"< %@ -> %@ >", name, value];
}
@end

int main() {
    @autoreleasepool {

        NSArray *pairs = @[
                       [Pair pairWithName:@"06-07" value:@"Ducks"],
                       [Pair pairWithName:@"00-01" value:@"Avalanche"],
                       [Pair pairWithName:@"02-03" value:@"Devils"],
                       [Pair pairWithName:@"01-02" value:@"Red Wings"],
                       [Pair pairWithName:@"03-04" value:@"Lightning"],
                       [Pair pairWithName:@"04-05" value:@"lockout"],
                       [Pair pairWithName:@"05-06" value:@"Hurricanes"],
                       [Pair pairWithName:@"99-00" value:@"Devils"],
                       [Pair pairWithName:@"07-08" value:@"Red Wings"],
                       [Pair pairWithName:@"08-09" value:@"Penguins"]];

        // optional 3rd arg: you can also specify a selector to compare the keys
        NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

        // it takes an array of sort descriptors, and it will be ordered by the
        // first one, then if it's a tie by the second one, etc.
        NSArray *sorted = [pairs sortedArrayUsingDescriptors:@[sd]];
        NSLog(@"%@", sorted);

    }

    return 0;
}

sort an array of composite structures, specifically name-value pairs, by the key name using a custom comparator.


Works with: Cocoa and Works with: GNUstep

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
    @"Joe Doe", @"name",
    [NSNumber numberWithUnsignedInt:42], @"age",
    [NSNull null], @"extra",
    nil];

NSDictionary *dict = @{
    @"name": @"Joe Doe",
    @"age": @42,
    @"extra": [NSNull null],
    };

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"Joe Doe" forKey:@"name"];
[dict setObject:[NSNumber numberWithInt:42] forKey:@"age"];

NSString *name = [dict objectForKey:@"name"];
unsigned age = [dict objectForKey:@"age"] unsignedIntValue];
id missing = [dict objectForKey:@"missing"];

create an associative array, or dictionary, using either NSDictionary for an immutable hash or NSMutableDictionary for a mutable dictionary. It only stores objects, so non-objects like integers must be boxed in NSNumber. The value can be accessed with objectForKey:, returning nil if the key does not exist. This is applicable in clang 3.1+ / Apple LLVM Compiler 4.0+ (XCode 4.4+).


#import <stdio.h>

BOOL iseven(int x)
{
  return (x&1) == 0;
}

@interface EthiopicMult : NSObject
+ (int)mult: (int)plier by: (int)plicand;
+ (int)halve: (int)a;
+ (int)double: (int)a;
@end

@implementation EthiopicMult
+ (int)mult: (int)plier by: (int)plicand
{
  int r = 0;
  while(plier >= 1) {
    if ( !iseven(plier) ) r += plicand;
    plier = [EthiopicMult halve: plier];
    plicand = [EthiopicMult double: plicand];
  }
  return r;
}

+ (int)halve: (int)a
{
  return (a>>1);
}

+ (int)double: (int)a
{
  return (a<<1);
}
@end

int main()
{
  @autoreleasepool {
    printf("%d\n", [EthiopicMult mult: 17 by: 34]);
  }
  return 0;
}

The code defines three functions for halving an integer, doubling an integer, and checking if an integer is even. These functions are then used to implement the Ethiopian multiplication method, which multiplies two numbers using only addition, doubling, and halving operations. The multiplication process involves creating a table, discarding rows with even numbers in the left column, and summing the remaining values in the right column.


#import <stdio.h>
#import <stdint.h>
#import <stdlib.h>
#import <string.h>
#import <Foundation/Foundation.h>

// this class exists to return a result between two
// vectors: if vectors have different "size", valid
// must be NO
@interface VResult : NSObject
{
 @private
  double value;
  BOOL valid;
}
+(instancetype)new: (double)v isValid: (BOOL)y;
-(instancetype)init: (double)v isValid: (BOOL)y;
-(BOOL)isValid;
-(double)value;
@end

@implementation VResult
+(instancetype)new: (double)v isValid: (BOOL)y
{
  return [[self alloc] init: v isValid: y];
}
-(instancetype)init: (double)v isValid: (BOOL)y
{
  if ((self == [super init])) {
    value = v;
    valid = y;
  }
  return self;
}
-(BOOL)isValid { return valid; }
-(double)value { return value; }
@end

@interface RCVector : NSObject
{
 @private
  double *vec;
  uint32_t size;
}
+(instancetype)newWithArray: (double *)v ofLength: (uint32_t)l;
-(instancetype)initWithArray: (double *)v ofLength: (uint32_t)l;
-(VResult *)dotProductWith: (RCVector *)v;
-(uint32_t)size;
-(double *)array;
-(void)free;
@end

@implementation RCVector
+(instancetype)newWithArray: (double *)v ofLength: (uint32_t)l
{
  return [[self alloc] initWithArray: v ofLength: l];
}
-(instancetype)initWithArray: (double *)v ofLength: (uint32_t)l
{
  if ((self = [super init])) {
    size = l;
    vec = malloc(sizeof(double) * l);
    if ( vec == NULL )
      return nil;
    memcpy(vec, v, sizeof(double)*l);
  }
  return self;
}
-(void)dealloc
{
  free(vec);
}
-(uint32_t)size { return size; }
-(double *)array { return vec; }
-(VResult *)dotProductWith: (RCVector *)v
{
  double r = 0.0;
  uint32_t i, s;
  double *v1;
  if ( [self size] != [v size] ) return [VResult new: r isValid: NO];
  s = [self size];
  v1 = [v array];
  for(i = 0; i < s; i++) {
    r += vec[i] * v1[i];
  }
  return [VResult new: r isValid: YES];
}
@end

double val1[] = { 1, 3, -5 };
double val2[] = { 4,-2, -1 };

int main()
{
  @autoreleasepool {
    RCVector *v1 = [RCVector newWithArray: val1 ofLength: sizeof(val1)/sizeof(double)];
    RCVector *v2 = [RCVector newWithArray: val2 ofLength: sizeof(val1)/sizeof(double)];
    VResult *r = [v1 dotProductWith: v2];
    if ( [r isValid] ) {
      printf("%lf\n", [r value]);
    } else {
      fprintf(stderr, "length of vectors differ\n");
    }
  }
  return 0;
}

Implement a function to calculate the dot product of two vectors of arbitrary length. The function multiplies corresponding elements from each vector and sums the products. The vectors must be of the same length. Example vectors used are [1, 3, -5] and [4, -2, -1].


NSLog(@"%@", [NSDate date]);
or (deprecated)NSLog(@"%@", [NSCalendarDate calendarDate]);

the system time in a specified unit. This can be used for debugging, network information, random number seeds, or program performance. The time is retrieved either by a system command or a built-in language function. It is related to the task of date formatting and retrieving system time.


Works with: Mac OS X version 10.5+
Works with: iOS version 1.0
@interface NSString (StripCharacters)
- (NSString *) stripCharactersInSet: (NSCharacterSet *) chars;
@end

@implementation NSString (StripCharacters)
- (NSString *) stripCharactersInSet: (NSCharacterSet *) chars {
    return [[self componentsSeparatedByCharactersInSet:chars] componentsJoinedByString:@""];
}
@end

To use:
    NSString *aString = @"She was a soul stripper. She took my heart!";
    NSCharacterSet* chars = [NSCharacterSet characterSetWithCharactersInString:@"aei"];

    // Display the NSString.
    NSLog(@"%@", [aString stripCharactersInSet:chars]);

"Function to remove specific characters from a given string"


#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        NSLog(@"I'm thinking of a number between 1 - 10. Can you guess what it is?\n");

        int rndNumber = arc4random_uniform(10) + 1;

        // Debug (Show rndNumber in console)
        //NSLog(@"Random number is %i", rndNumber);

        int userInput;

        do {

            NSLog(@"Input the number below\n");
            scanf("%i", &userInput);

            if (userInput > 10) {

                NSLog(@"Please enter a number less than 10\n");
            }

            if (userInput > 10 || userInput != rndNumber) {

                NSLog(@"Your guess %i is incorrect, please try again", userInput);

            } else {

                NSLog(@"Your guess %i is correct!", userInput);
            }

        } while (userInput > 10 || userInput != rndNumber);
    }
    return 0;
}

"Implement a number guessing game where the computer selects a number between 1 and 10. The player is repeatedly prompted to guess the number until the correct number is guessed, upon which a 'Well guessed!' message is displayed and the program terminates. A conditional loop is used to facilitate repeated guessing."


+ (double) distanceBetweenLat1:(double)lat1 lon1:(double)lon1
                          lat2:(double)lat2 lon2:(double)lon2 {
    //degrees to radians
    double lat1rad = lat1 * M_PI/180;
    double lon1rad = lon1 * M_PI/180;
    double lat2rad = lat2 * M_PI/180;
    double lon2rad = lon2 * M_PI/180;

    //deltas
    double dLat = lat2rad - lat1rad;
    double dLon = lon2rad - lon1rad;

    double a = sin(dLat/2) * sin(dLat/2) + sin(dLon/2) * sin(dLon/2) * cos(lat1rad) * cos(lat2rad);
    double c = 2 * asin(sqrt(a));
    double R = 6372.8;
    return R * c;
}

Implement a function to calculate the great-circle distance between two points on a sphere using the Haversine formula. The function takes the coordinates of Nashville International Airport (BNA) and Los Angeles International Airport (LAX) as input and returns the distance between them. The calculation uses the recommended earth radius of 6372.8 km or 6371 km, depending on the level of precision required.


#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    @autoreleasepool {

        NSError        *error;
        NSURLResponse *response;
        NSData *data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://rosettacode.org"]]
                                                returningResponse:&response
                                                            error:&error];

        NSLog(@"%@", [[NSString alloc] initWithData:data
                                              encoding:NSUTF8StringEncoding]);

    }
    return 0;
}

Print the content of a specified URL to the console using HTTP request.


- (NSArray *) toCharArray {

	NSMutableArray *characters = [[NSMutableArray alloc] initWithCapacity:[self length]];
	for (int i=0; i < [self length]; i++) {
		NSString *ichar  = [NSString stringWithFormat:@"%C", [self characterAtIndex:i]];
		[characters addObject:ichar];
	}

	return characters;
}

+ (BOOL) luhnCheck:(NSString *)stringToTest {

	NSArray *stringAsChars = [stringToTest toCharArray];

	BOOL isOdd = YES;
	int oddSum = 0;
	int evenSum = 0;

	for (int i = [stringToTest length] - 1; i >= 0; i--) {

		int digit = [(NSString *)stringAsChars[i] intValue];

		if (isOdd)
			oddSum += digit;
		else
			evenSum += digit/5 + (2*digit) % 10;

		isOdd = !isOdd;
	}

	return ((oddSum + evenSum) % 10 == 0);
}

BOOL test0 = [self luhnCheck:@"49927398716"]; //Result = YES
BOOL test1 = [self luhnCheck:@"49927398717"]; //Result = NO
BOOL test2 = [self luhnCheck:@"1234567812345678"]; //Result = NO
BOOL test3 = [self luhnCheck:@"1234567812345670"]; //Result = YES

The code validates credit card numbers using the Luhn test. It reverses the input number, calculates the sum of odd and even positioned digits (with even digits being doubled and if the result is greater than nine, the digits of the result are summed). If the total sum ends in zero, the number is deemed valid. The code tests this functionality on four given numbers.


@interface NSString (RosettaCodeAddition)
- (NSString *) repeatStringByNumberOfTimes: (NSUInteger) times;
@end

@implementation NSString (RosettaCodeAddition)
- (NSString *) repeatStringByNumberOfTimes: (NSUInteger) times {
    return [@"" stringByPaddingToLength:[self length]*times withString:self startingAtIndex:0];
}
@end

    // Instantiate an NSString by sending an NSString literal our new
    // -repeatByNumberOfTimes: selector.
    NSString *aString = [@"ha" repeatStringByNumberOfTimes:5];

    // Display the NSString.
    NSLog(@"%@", aString);

extend the NSString class in Objective-C to include a method that repeats a given string or character a specified number of times. This is achieved using the language feature of categories, which allows for the addition of methods to existing classes without the need for subclassing. The method is applicable to all instances of the class and its subclasses. An example use case is repeating the string "ha" 5 times or the character "*" 5 times.


Works with: Mac OS X version 10.4+
Works with: iOS version 3.0+
NSString *str = @"I am a string";
NSString *regex = @".*string$";

// Note: the MATCHES operator matches the entire string, necessitating the ".*"
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];

if ([pred evaluateWithObject:str]) {
    NSLog(@"ends with 'string'");
}

NSRegularExpressionSearch[edit]

Works with: Mac OS X version 10.7+
Works with: iOS version 3.2+
NSString *str = @"I am a string";
if ([str rangeOfString:@"string$" options:NSRegularExpressionSearch].location != NSNotFound) {
    NSLog(@"Ends with 'string'");
}

Works with: Mac OS X version 10.7+
Works with: iOS version 4.0+ undocumented
NSString *orig = @"I am the original string";
NSString *result = [orig stringByReplacingOccurrencesOfString:@"original"
                                                   withString:@"modified"
                                                      options:NSRegularExpressionSearch
                                                        range:NSMakeRange(0, [orig length])];
NSLog(@"%@", result);

NSRegularExpression[edit]
Works with: Mac OS X version 10.7+
Works with: iOS version 4.0+

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"string$"
                                                                       options:0
                                                                         error:NULL];
NSString *str = @"I am a string";
if ([regex rangeOfFirstMatchInString:str
                             options:0
                               range:NSMakeRange(0, [str length])
     ].location != NSNotFound) {
    NSLog(@"Ends with 'string'");
}

for (NSTextCheckingResult *match in [regex matchesInString:str
                                                   options:0
                                                     range:NSMakeRange(0, [str length])
                                     ]) {
    // match.range gives the range of the whole match
    // [match rangeAtIndex:i] gives the range of the i'th capture group (starting from 1)
}

NSString *orig = @"I am the original string";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"original"
                                                                       options:0
                                                                         error:NULL];
NSString *result = [regex stringByReplacingMatchesInString:orig
                                                   options:0
                                                     range:NSMakeRange(0, [orig length])
                                              withTemplate:@"modified"];
NSLog(@"%@", result);

"Matches a string against a regular expression, identifies the location of the match, performs substitution on part of the string using the regular expression, and loops through all matches for substitution."


@interface NSString (CountSubstrings)
- (NSUInteger)occurrencesOfSubstring:(NSString *)subStr;
@end

@implementation NSString (CountSubstrings)
- (NSUInteger)occurrencesOfSubstring:(NSString *)subStr {
  return [[self componentsSeparatedByString:subStr] count] - 1;
}
@end

int main(int argc, const char *argv[]) {
  @autoreleasepool {

    NSLog(@"%lu", [@"the three truths" occurrencesOfSubstring:@"th"]);
    NSLog(@"%lu", [@"ababababab" occurrencesOfSubstring:@"abab"]);
    NSLog(@"%lu", [@"abaabba*bbaba*bbab" occurrencesOfSubstring:@"a*b"]);

  }
  return 0;
}

The code defines a function to count the number of non-overlapping occurrences of a specific substring within a given string. The function takes two parameters: the main string and the substring to search for. It returns an integer representing the count of non-overlapping occurrences. The function does not count overlapping substrings and aims to yield the highest number of non-overlapping matches, either from left-to-right or right-to-left.


Works with: GNUstep

#import <Foundation/NSObject.h>

@interface TowersOfHanoi: NSObject {
	int pegFrom;
	int pegTo;
	int pegVia;
	int numDisks;
}

-(void) setPegFrom: (int) from andSetPegTo: (int) to andSetPegVia: (int) via andSetNumDisks: (int) disks;
-(void) movePegFrom: (int) from andMovePegTo: (int) to andMovePegVia: (int) via andWithNumDisks: (int) disks;
@end

#import "TowersOfHanoi.h"
@implementation TowersOfHanoi

-(void) setPegFrom: (int) from andSetPegTo: (int) to andSetPegVia: (int) via andSetNumDisks: (int) disks {
	pegFrom = from;
	pegTo = to;
	pegVia = via;
	numDisks = disks;
}

-(void) movePegFrom: (int) from andMovePegTo: (int) to andMovePegVia: (int) via andWithNumDisks: (int) disks {
	if (disks == 1) {
            printf("Move disk from pole %i to pole %i\n", from, to);
        } else {
 			[self movePegFrom: from andMovePegTo: via andMovePegVia: to andWithNumDisks: disks-1];
			[self movePegFrom: from andMovePegTo: to andMovePegVia: via andWithNumDisks: 1];
			[self movePegFrom: via andMovePegTo: to andMovePegVia: from andWithNumDisks: disks-1];
        }
}

@end

#import <stdio.h>
#import "TowersOfHanoi.h"

int main( int argc, const char *argv[] ) {
	@autoreleasepool {

		TowersOfHanoi *tower = [[TowersOfHanoi alloc] init];

		int from = 1;
		int to = 3;
		int via = 2;
		int disks = 3;

		[tower setPegFrom: from andSetPegTo: to andSetPegVia: via andSetNumDisks: disks];

		[tower movePegFrom: from andMovePegTo: to andMovePegVia: via andWithNumDisks: disks];

	}
	return 0;
}

The following codes implement a recursive solution to the Towers of Hanoi problem. The codes are compatible with XCode/Cocoa on MacOS. It includes three parts: the interface in TowersOfHanoi.h, the implementation in TowersOfHanoi.m, and the test code in TowersTest.m.


Character Length[edit]

// Return the length in characters
// XXX: does not (always) count Unicode characters (code points)!
unsigned int numberOfCharacters = [@"møøse" length];  // 5

int realCharacterCount = [s lengthOfBytesUsingEncoding: NSUTF32StringEncoding] / 4;
Byte Length[edit]

int byteCount = [@"møøse" length] * 2; // 10

// Return the number of bytes depending on the encoding,
// here explicitly UTF-8
unsigned numberOfBytes =
   [@"møøse" lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; // 7

determine the character and byte length of a string, considering different encodings like UTF-8 and UTF-16. The character length is based on individual Unicode code points, not user-visible graphemes. The codes also handle non-BMP code points correctly. The byte length is calculated by encoding the string in UTF-32 and dividing by 4 or by doubling the number of 16-bit values used to encode a string in UTF-16. The codes also provide the string length in graphemes if the language supports it. The encoding used is explicitly specified to avoid ambiguity.


#import <Foundation/Foundation.h>

@interface NSMutableArray (KnuthShuffle)
- (void)knuthShuffle;
@end
@implementation NSMutableArray (KnuthShuffle)
- (void)knuthShuffle {
  for (NSUInteger i = self.count-1; i > 0; i--) {
    NSUInteger j = arc4random_uniform(i+1);
    [self exchangeObjectAtIndex:i withObjectAtIndex:j];
  }
}
@end

int main() {
  @autoreleasepool {
    NSMutableArray *x = [NSMutableArray arrayWithObjects:@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, nil];
    [x knuthShuffle];
    NSLog(@"%@", x);
  }
  return 0;
}

implement the Knuth shuffle (also known as the Fisher-Yates shuffle) algorithm. This algorithm randomly shuffles the elements of an array in-place. The shuffling process involves iterating from the last index of the array down to 1, and for each index, swapping the element at that index with an element at a random index within the range of 0 to the current index. If in-place modification of the array is not possible in the used programming language, the algorithm can be adjusted to return a new shuffled array. The algorithm can also be modified to iterate from left to right if needed.


switch (NSHostByteOrder()) {
  case NS_BigEndian:
    NSLog(@"%@", @"Big Endian");
    break;
  case NS_LittleEndian:
    NSLog(@"%@", @"Little Endian");
    break;
  case NS_UnknownByteOrder:
    NSLog(@"%@", @"endianness unknown");
    break;
}

switch ([NSRunningApplication currentApplication].executableArchitecture) {
  case NSBundleExecutableArchitectureI386:
    NSLog(@"%@", @"i386 32-bit");
    break;

  case NSBundleExecutableArchitectureX86_64:
    NSLog(@"%@", @"x86_64 64-bit");
    break;

  case NSBundleExecutableArchitecturePPC:
    NSLog(@"%@", @"PPC 32-bit");
    break;

  case NSBundleExecutableArchitecturePPC64:
    NSLog(@"%@", @"PPC64 64-bit");
    break;

  default:
    NSLog(@"%@", @"Unknown");
    break;
}

"Code prints the word size and endianness of the host machine, specifically designed for Mac OS X 10.6+ architecture."


Works with: Objective-C version 2.0+
Works with: GNUstep
Works with: Cocoa
NSArray *collect;
//...
for(Type i in collect){
   NSLog(@"%@", i);
}

Works with: Objective-C version <2.0
NSArray *collect;
//...
NSEnumerator *enm = [collect objectEnumerator];
id i;
while( (i = [enm nextObject]) ) {
  // do something with object i
}

Iterates and prints each element in a collection in order using a "for each" loop or another loop if "for each" isn't available. The collection can be any object that adopts the NSFastEnumeration protocol, always using OpenStep compatible frameworks.


Works with: GNUstep
Works with: Cocoa
NSString *text = @"Hello,How,Are,You,Today";
NSArray *tokens = [text componentsSeparatedByString:@","];
NSString *result = [tokens componentsJoinedByString:@"."];
NSLog(result);

"Tokenizes a string by commas into an array, and displays the words to the user separated by a period, including a trailing period."


Works with: GCC
Works with: OpenStep
Works with: GNUstep

if( [[NSScanner scannerWithString:@"-123.4e5"] scanFloat:NULL] )
	NSLog( @"\"-123.4e5\" is numeric" );
else
	NSLog( @"\"-123.4e5\" is not numeric" );
if( [[NSScanner scannerWithString:@"Not a number"] scanFloat:NULL] )
	NSLog( @"\"Not a number\" is numeric" );
else
	NSLog( @"\"Not a number\" is not numeric" );
// prints: "-123.4e5" is numeric
// prints: "Not a number" is not numeric

BOOL isNumeric(NSString *s)
{
   NSScanner *sc = [NSScanner scannerWithString: s];
   if ( [sc scanFloat:NULL] )
   {
      return [sc isAtEnd];
   }
   return NO;
}

BOOL isNumericI(NSString *s)
{
   NSUInteger len = [s length];
   NSUInteger i;
   BOOL status = NO;

   for(i=0; i < len; i++)
   {
       unichar singlechar = [s characterAtIndex: i];
       if ( (singlechar == ' ') && (!status) )
       {
         continue;
       }
       if ( ( singlechar == '+' ||
              singlechar == '-' ) && (!status) ) { status=YES; continue; }
       if ( ( singlechar >= '0' ) &&
            ( singlechar <= '9' ) )
       {
          status = YES;
       } else {
          return NO;
       }
   }
   return (i == len) && status;
}

The code creates a boolean function that checks if a given string is numeric, including floating point and negative numbers. It uses the NSScanner class to scan the string and the scanFloat method to determine if the string is numeric. The function also checks if the scanner has reached the end of the string after parsing the float, ensuring the string is completely numeric. It also includes a manual scan function to check if the number is a positive or negative integer, allowing for spaces before the number but not after, and only allowing '+' or '-' symbols attached directly to the number.


NSString *s = @"12345";
int i = [s intValue] + 1;
s = [NSString stringWithFormat:@"%i", i]


#import <Foundation/Foundation.h>

@interface NSMutableArray (SattoloCycle)
- (void)sattoloCycle;
@end
@implementation NSMutableArray (SattoloCycle)
- (void)sattoloCycle {
  for (NSUInteger i = self.count-1; i > 0; i--) {
    NSUInteger j = arc4random_uniform(i);
    [self exchangeObjectAtIndex:i withObjectAtIndex:j];
  }
}
@end

implement the Sattolo cycle algorithm which shuffles an array ensuring each element ends up in a new position. The algorithm works by iterating from the last index to the first, selecting a random index within the range, and swapping the elements at these two indices. The algorithm modifies the input array in-place, but can be adjusted to return a new array or iterate from left to right if necessary. The key distinction from the Knuth shuffle is the range from which the random index is selected.


// FizzBuzz in Objective-C
#import <Foundation/Foundation.h>

int main(int argc, char* argv[]) {
	for (NSInteger i=1; I <= 101; i++) {
		if (i % 15 == 0) {
		    NSLog(@"FizzBuzz\n");
		} else if (i % 3 == 0) {
		    NSLog(@"Fizz\n");
		} else if (i % 5 == 0) {
		    NSLog(@"Buzz\n");
		} else {
		    NSLog(@"%li\n", i);
		}
	}
}

print numbers from 1 to 100, replacing multiples of three with 'Fizz', multiples of five with 'Buzz', and multiples of both three and five with 'FizzBuzz'.


Works with: GCC version 4.0.1 (apple)

- (float) sum:(NSMutableArray *)array
{
	int i, sum, value;
	sum = 0;
	value = 0;

	for (i = 0; i < [array count]; i++) {
		value = [[array objectAtIndex: i] intValue];
		sum += value;
	}

	return suml;
}

- (float) prod:(NSMutableArray *)array
{
	int i, prod, value;
	prod = 0;
	value = 0;

	for (i = 0; i < [array count]; i++) {
		value = [[array objectAtIndex: i] intValue];
		prod *= value;
	}

	return suml;
}

Calculates the sum and product of all integers in an array.


NSString *original = @"Literal String";
NSString *new = [original copy];
NSString *anotherNew = [NSString stringWithString:original];
NSString *newMutable = [original mutableCopy];

NSMutableString *original = [NSMutableString stringWithString:@"Literal String"];
NSString *immutable = [original copy];
NSString *anotherImmutable = [NSString stringWithString:original];
NSMutableString *mutable = [original mutableCopy];

const char *cstring = "I'm a plain C string";
NSString *string = [NSString stringWithUTF8String:cstring];

char bytes[] = "some data";
NSString *string = [[NSString alloc] initWithBytes:bytes length:9 encoding:NSASCIIStringEncoding];

The code implements the task of copying a string. It differentiates between copying the string's content and creating an additional reference to the existing string. For immutable strings, it either increases the reference count or creates a mutable copy. The code also handles mutable strings, creating either a new mutable or immutable string. It also includes functionality for copying a CString into an NSString, and copying from data that may not be null-terminated. If a C string is needed, it utilizes standard functions like strcpy.


#import <Foundation/Foundation.h>

@interface Hofstadter : NSObject
+ (int)M: (int)n;
+ (int)F: (int)n;
@end

@implementation Hofstadter
+ (int)M: (int)n
{
  if ( n == 0 ) return 0;
  return n - [self F: [self M: (n-1)]];
}
+ (int)F: (int)n
{
  if ( n == 0 ) return 1;
  return n - [self M: [self F: (n-1)]];
}
@end

int main()
{
  int i;

  for(i=0; i < 20; i++) {
    printf("%3d ", [Hofstadter F: i]);
  }
  printf("\n");
  for(i=0; i < 20; i++) {
    printf("%3d ", [Hofstadter M: i]);
  }
  printf("\n");
  return 0;
}

implement two mutually recursive functions to calculate the Hofstadter Female and Male sequences. The functions follow the rules of mutual recursion, where the first function calls the second, and the second function calls the first. The sequences are defined with specific base cases and recursive cases. The code also considers the language-specific rules for prior declaration in Objective-C.


NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F";
NSString *normal = [encoded stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", normal);

Works with: Mac OS X version 10.9+Works with: iOS version 7+
NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F";
NSString *normal = [encoded stringByRemovingPercentEncoding];
NSLog(@"%@", normal);

provide a function to convert URL-encoded strings back into their original unencoded form. It includes test cases for strings like "http%3A%2F%2Ffoo%20bar%2F", "google.com/search?q=%60Abdu%27l-Bah%C3%A1", and "%25%32%35".


#import <Foundation/Foundation.h>

@interface NSArray (BinarySearch)
// Requires all elements of this array to implement a -compare: method which
// returns a NSComparisonResult for comparison.
// Returns NSNotFound when not found
- (NSInteger) binarySearch:(id)key;
@end

@implementation NSArray (BinarySearch)
- (NSInteger) binarySearch:(id)key {
  NSInteger lo = 0;
  NSInteger hi = [self count] - 1;
  while (lo <= hi) {
    NSInteger mid = lo + (hi - lo) / 2;
    id midVal = self[mid];
    switch ([midVal compare:key]) {
    case NSOrderedAscending:
      lo = mid + 1;
      break;
    case NSOrderedDescending:
      hi = mid - 1;
      break;
    case NSOrderedSame:
      return mid;
    }
  }
  return NSNotFound;
}
@end

int main()
{
  @autoreleasepool {

    NSArray *a = @[@1, @3, @4, @5, @6, @7, @8, @9, @10];
    NSLog(@"6 is at position %d", [a binarySearch:@6]); // prints 4

  }
  return 0;
}

#import <Foundation/Foundation.h>

@interface NSArray (BinarySearchRecursive)
// Requires all elements of this array to implement a -compare: method which
// returns a NSComparisonResult for comparison.
// Returns NSNotFound when not found
- (NSInteger) binarySearch:(id)key inRange:(NSRange)range;
@end

@implementation NSArray (BinarySearchRecursive)
- (NSInteger) binarySearch:(id)key inRange:(NSRange)range {
  if (range.length == 0)
    return NSNotFound;
  NSInteger mid = range.location + range.length / 2;
  id midVal = self[mid];
  switch ([midVal compare:key]) {
  case NSOrderedAscending:
    return [self binarySearch:key
                      inRange:NSMakeRange(mid + 1, NSMaxRange(range) - (mid + 1))];
  case NSOrderedDescending:
    return [self binarySearch:key
                      inRange:NSMakeRange(range.location, mid - range.location)];
  default:
    return mid;
  }
}
@end

int main()
{
  @autoreleasepool {

    NSArray *a = @[@1, @3, @4, @5, @6, @7, @8, @9, @10];
    NSLog(@"6 is at position %d", [a binarySearch:@6]); // prints 4

  }
  return 0;
}

Works with: Mac OS X version 10.6+
#import <Foundation/Foundation.h>

int main()
{
  @autoreleasepool {

    NSArray *a = @[@1, @3, @4, @5, @6, @7, @8, @9, @10];
    NSLog(@"6 is at position %lu", [a indexOfObject:@6
                                      inSortedRange:NSMakeRange(0, [a count])
                                            options:0
                                    usingComparator:^(id x, id y){ return [x compare: y]; }]); // prints 4

  }
  return 0;
}

#import <Foundation/Foundation.h>

CFComparisonResult myComparator(const void *x, const void *y, void *context) {
  return [(__bridge id)x compare:(__bridge id)y];
}

int main(int argc, const char *argv[]) {
  @autoreleasepool {

    NSArray *a = @[@1, @3, @4, @5, @6, @7, @8, @9, @10];
    NSLog(@"6 is at position %ld", CFArrayBSearchValues((__bridge CFArrayRef)a,
                                                        CFRangeMake(0, [a count]),
                                                        (__bridge const void *)@6,
                                                        myComparator,
                                                        NULL)); // prints 4

  }
  return 0;
}

The code implements a binary search algorithm, which is used to find a specific value in a sorted integer array. The algorithm divides the array into halves and continues to narrow down the search range until the target value is found. The code provides both recursive and iterative implementations of the binary search. It also handles cases where there are multiple values equal to the target value and returns the index of the target value if found. Additionally, the code includes variations of the binary search algorithm that return the leftmost and rightmost insertion points for the target value. The code is also designed to avoid overflow bugs.


NSArray *args = [[NSProcessInfo processInfo] arguments];
NSLog(@"This program is named %@.", [args objectAtIndex:0]);
NSLog(@"There are %d arguments.", [args count] - 1);
for (i = 1; i < [args count]; ++i){
    NSLog(@"the argument #%d is %@", i, [args objectAtIndex:i]);
}

retrieve and print the command-line arguments given to the program. It uses both the regular C mechanism and an additional Objective-C method to get the arguments as string objects inside an array. The example command line used is 'myprogram -c "alpha beta" -h "gamma"'. The program also includes functionality for parsing these arguments intelligently.


Works with: 10.7+ version Xcode 4.4+
NSString *jsonString = @"{ \"foo\": 1, \"bar\": [10, \"apples\"] }";
id obj = [NSJSONSerialization
    JSONObjectWithData: [jsonString dataUsingEncoding: NSUTF8StringEncoding]
               options: 0
                 error: NULL];
NSLog(@"%@", obj);

NSDictionary *dict = @{ @"blue": @[@1, @2], @"ocean": @"water"};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject: dict
                                                   options: 0
                                                     error: NULL];
NSString *jsonString2 = [[NSString alloc] initWithData: jsonData
                                              encoding: NSUTF8StringEncoding];
NSLog(@"%@", jsonString2);

"Load a JSON string into a data structure, create a new data structure, serialize it into JSON, and validate the JSON."


NSLog(@"%@", [[NSProcessInfo processInfo] hostName]);

2010-09-16 16:20:00.000 Playground[1319:a0f] sierra117.local // Hostname is sierra117.local.

finds the hostname of the current system where the routine is running in Cocoa / Cocoa Touch / GNUstep.


implement run-length encoding and decoding functions for strings containing uppercase characters. The encoding function compresses repeated characters by storing the length of the run, and the decoding function reverses this compression.


#import <Foundation/Foundation.h>

int main()
{
  @autoreleasepool {

    NSString *s = @"hello";
    printf("%s%s\n", [s UTF8String], " literal");

    NSString *s2 = [s stringByAppendingString:@" literal"];
    // or, NSString *s2 = [NSString stringWithFormat:@"%@%@", s, @" literal"];
    puts([s2 UTF8String]);
    /* or */
    NSMutableString *s3 = [NSMutableString stringWithString: s];
    [s3 appendString: @" literal"];
    puts([s3 UTF8String]);

  }
  return 0;
}

Initializes two string variables, one with a text value and the other as a concatenation of the first variable and a string literal, then displays their content.


NSString *normal = @"http://foo bar/";
NSString *encoded = [normal stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", encoded);

Works with: Mac OS X version 10.9+
Works with: iOS version 7+
NSString *normal = @"http://foo bar/";
NSString *encoded = [normal stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
NSLog(@"%@", encoded);

The code provides a function to convert a given string into its URL encoding representation. It converts special, control, and extended characters into a percent symbol followed by a two-digit hexadecimal code. For instance, a space character is encoded as %20. The code adheres to the rule that every character except 0-9, A-Z, and a-z requires conversion. It also supports variations like lowercase escapes and different encodings for special characters as per different standards like RFC 3986 and HTML 5. Optionally, it allows the use of an exception string with symbols that don't need conversion. It also provides options for encoding different parts of the URL using various allowed character sets.


Translation of: Java

#import <Foundation/Foundation.h>

@interface HuffmanTree : NSObject {
	int freq;
}
-(instancetype)initWithFreq:(int)f;
@property (nonatomic, readonly) int freq;
@end

@implementation HuffmanTree
@synthesize freq; // the frequency of this tree
-(instancetype)initWithFreq:(int)f {
	if (self = [super init]) {
		freq = f;
	}
	return self;
}
@end

const void *HuffmanRetain(CFAllocatorRef allocator, const void *ptr) {
	return (__bridge_retained const void *)(__bridge id)ptr;
}
void HuffmanRelease(CFAllocatorRef allocator, const void *ptr) {
	(void)(__bridge_transfer id)ptr;
}
CFComparisonResult HuffmanCompare(const void *ptr1, const void *ptr2, void *unused) {
	int f1 = ((__bridge HuffmanTree *)ptr1).freq;
	int f2 = ((__bridge HuffmanTree *)ptr2).freq;
	if (f1 == f2)
		return kCFCompareEqualTo;
	else if (f1 > f2)
		return kCFCompareGreaterThan;
	else
		return kCFCompareLessThan;
}

@interface HuffmanLeaf : HuffmanTree {
	char value; // the character this leaf represents
}
@property (readonly) char value;
-(instancetype)initWithFreq:(int)f character:(char)c;
@end

@implementation HuffmanLeaf
@synthesize value;
-(instancetype)initWithFreq:(int)f character:(char)c {
	if (self = [super initWithFreq:f]) {
		value = c;
	}
	return self;
}
@end

@interface HuffmanNode : HuffmanTree {
	HuffmanTree *left, *right; // subtrees
}
@property (readonly) HuffmanTree *left, *right;
-(instancetype)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r;
@end

@implementation HuffmanNode
@synthesize left, right;
-(instancetype)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r {
	if (self = [super initWithFreq:l.freq+r.freq]) {
		left = l;
		right = r;
	}
	return self;
}
@end

HuffmanTree *buildTree(NSCountedSet *chars) {

	CFBinaryHeapCallBacks callBacks = {0, HuffmanRetain, HuffmanRelease, NULL, HuffmanCompare};
	CFBinaryHeapRef trees = CFBinaryHeapCreate(NULL, 0, &callBacks, NULL);

	// initially, we have a forest of leaves
	// one for each non-empty character
	for (NSNumber *ch in chars) {
		int freq = [chars countForObject:ch];
		if (freq > 0)
			CFBinaryHeapAddValue(trees, (__bridge const void *)[[HuffmanLeaf alloc] initWithFreq:freq character:(char)[ch intValue]]);
	}

	NSCAssert(CFBinaryHeapGetCount(trees) > 0, @"String must have at least one character");
	// loop until there is only one tree left
	while (CFBinaryHeapGetCount(trees) > 1) {
		// two trees with least frequency
		HuffmanTree *a = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
		CFBinaryHeapRemoveMinimumValue(trees);
		HuffmanTree *b = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
		CFBinaryHeapRemoveMinimumValue(trees);

		// put into new node and re-insert into queue
		CFBinaryHeapAddValue(trees, (__bridge const void *)[[HuffmanNode alloc] initWithLeft:a right:b]);
	}
	HuffmanTree *result = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
	CFRelease(trees);
	return result;
}

void printCodes(HuffmanTree *tree, NSMutableString *prefix) {
	NSCAssert(tree != nil, @"tree must not be nil");
	if ([tree isKindOfClass:[HuffmanLeaf class]]) {
		HuffmanLeaf *leaf = (HuffmanLeaf *)tree;

		// print out character, frequency, and code for this leaf (which is just the prefix)
		NSLog(@"%c\t%d\t%@", leaf.value, leaf.freq, prefix);

	} else if ([tree isKindOfClass:[HuffmanNode class]]) {
		HuffmanNode *node = (HuffmanNode *)tree;

		// traverse left
		[prefix appendString:@"0"];
		printCodes(node.left, prefix);
		[prefix deleteCharactersInRange:NSMakeRange([prefix length]-1, 1)];

		// traverse right
		[prefix appendString:@"1"];
		printCodes(node.right, prefix);
		[prefix deleteCharactersInRange:NSMakeRange([prefix length]-1, 1)];
	}
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {

	NSString *test = @"this is an example for huffman encoding";

	// read each character and record the frequencies
	NSCountedSet *chars = [[NSCountedSet alloc] init];
	int n = [test length];
	for (int i = 0; i < n; i++)
		[chars addObject:@([test characterAtIndex:i])];

	// build tree
	HuffmanTree *tree = buildTree(chars);

	// print out results
	NSLog(@"SYMBOL\tWEIGHT\tHUFFMAN CODE");
	printCodes(tree, [NSMutableString string]);

    }
    return 0;
}

The code generates a Huffman encoding for each character in a given string. It first creates a priority queue with a leaf node for each symbol. It then constructs a binary tree by continuously removing the two nodes with the highest priority and creating a new internal node with these two nodes as children. The final node is the root of the tree. The code then traverses the tree from root to leaves, assigning '0' for one branch and '1' for the other at each node. The accumulated zeros and ones at each leaf constitute the Huffman encoding for the corresponding symbol. This code uses Apple's Core Foundation library for its binary heap and is compatible with Mac OS X.


Works with: GNUstep
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>

@interface ClickMe : NSWindow
{
  NSButton *_button;
  NSTextField *_text;
  int _counter;
}
- (void)applicationDidFinishLaunching: (NSNotification *)notification;
- (BOOL)applicationShouldTerminateAfterLastWindowClosed: (NSNotification *)notification;
- (void)advanceCounter: (id)sender;
@end

@implementation ClickMe : NSWindow
-(instancetype) init
{
  NSButton *button = [[NSButton alloc] init];
  [button setButtonType: NSToggleButton];
  [button setTitle: @"Click Me"];
  [button sizeToFit];
  [button setTarget: self];
  [button setAction: @selector(advanceCounter:)];
  NSRect buttonRect = [button frame];

  NSTextField *text = [[NSTextField alloc]
	   initWithFrame: NSMakeRect(buttonRect.origin.x, buttonRect.size.height,
				     buttonRect.size.width, buttonRect.size.height)];
  [text setAlignment: NSCenterTextAlignment];
  [text setEditable: NO];
  [text setStringValue: @"There have been no clicks yet"];
  [text sizeToFit];

  // reset size of button according to size of (larger...?) text
  [button
    setFrameSize: NSMakeSize( [text frame].size.width, buttonRect.size.height ) ];

  int totalWindowHeight = buttonRect.size.height + [text frame].size.height;

  if ((self = [super initWithContentRect: NSMakeRect(100, 100,
				    [text frame].size.width, totalWindowHeight)
        styleMask: (NSTitledWindowMask | NSClosableWindowMask)
      backing: NSBackingStoreBuffered
      defer: NO])) {
    _counter = 0;
    _button = button;
    _text = text;

    [[self contentView] addSubview: _text];
    [[self contentView] addSubview: _button];

    [self setTitle: @"Click Me!"];
    [self center];
  }
  return self;
}

- (void)applicationDidFinishLaunching: (NSNotification *)notification
{
  [self orderFront: self];
}

- (BOOL)applicationShouldTerminateAfterLastWindowClosed: (NSNotification *)notification
{
  return YES;
}

- (void)advanceCounter: (id)sender
{
  [_text setStringValue: [NSString stringWithFormat: @"Clicked %d times", ++_counter]];
}
@end

int main()
{
  @autoreleasepool {
    NSApplication *app =  [NSApplication sharedApplication];
    ClickMe *clickme = [[ClickMe alloc] init];
    [app setDelegate: clickme];
    [app run];
  }
  return 0;
}

Implement a windowed application with a label and a button. The label initially displays "There have been no clicks yet". The button, labelled "click me", updates the label to show the number of times it has been clicked when interacted with.


NSArray *arr1 = @[@1, @2, @3];
NSArray *arr2 = @[@4, @5, @6];
NSArray *arr3 = [arr1 arrayByAddingObjectsFromArray:arr2];

NSArray *arr1 = @[@1, @2, @3];
NSArray *arr2 = @[@4, @5, @6];
NSMutableArray *arr3 = [NSMutableArray arrayWithArray:arr1];
[arr3 addObjectsFromArray:arr2];

demonstrate how to concatenate two arrays, including both mutable and immutable arrays, in the given programming language.


Works with: XCode 4.5.1

//--------------------------------------------------------------------
// Person class

@interface Person : NSObject {
    NSUInteger _candidateIndex;
}
@property (nonatomic, strong)   NSString*   name;
@property (nonatomic, strong)   NSArray*    prefs;
@property (nonatomic, weak)     Person*     fiance;
@end

@implementation Person
+ (instancetype)named:(NSString *)name {
    return [[self alloc] initWithName:name];
}
- (instancetype)initWithName:(NSString *)name {
    if ((self = [super init])) {
        _name = name;
        _prefs = nil;
        _fiance = nil;
        _candidateIndex = 0;
    }
    return self;
}
- (BOOL)prefers:(Person *)p {
    return [_prefs indexOfObject:p] < [_prefs indexOfObject:_fiance];
}
- (Person *)nextCandidateNotYetProposedTo {
    if (_candidateIndex >= _prefs.count) return nil;
    return _prefs[_candidateIndex++];
}
- (void)engageTo:(Person *)p {
    if (p.fiance) p.fiance.fiance = nil;
    p.fiance = self;
    if (self.fiance) self.fiance.fiance = nil;
    self.fiance = p;
}
- (NSString *)description {
    return _name;
}
@end

//--------------------------------------------------------------------

BOOL isStable(NSArray *men) {
    NSArray *women = ((Person *)men[0]).prefs;
    for (Person *guy in men) {
        for (Person *gal in women) {
            if ([guy prefers:gal] && [gal prefers:guy])
                return NO;
        }
    }
    return YES;
}

//--------------------------------------------------------------------

void doMarriage() {
    Person *abe  = [Person named:@"abe"];
    Person *bob  = [Person named:@"bob"];
    Person *col  = [Person named:@"col"];
    Person *dan  = [Person named:@"dan"];
    Person *ed   = [Person named:@"ed"];
    Person *fred = [Person named:@"fred"];
    Person *gav  = [Person named:@"gav"];
    Person *hal  = [Person named:@"hal"];
    Person *ian  = [Person named:@"ian"];
    Person *jon  = [Person named:@"jon"];
    Person *abi  = [Person named:@"abi"];
    Person *bea  = [Person named:@"bea"];
    Person *cath = [Person named:@"cath"];
    Person *dee  = [Person named:@"dee"];
    Person *eve  = [Person named:@"eve"];
    Person *fay  = [Person named:@"fay"];
    Person *gay  = [Person named:@"gay"];
    Person *hope = [Person named:@"hope"];
    Person *ivy  = [Person named:@"ivy"];
    Person *jan  = [Person named:@"jan"];

    abe.prefs  = @[ abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay ];
    bob.prefs  = @[ cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay ];
    col.prefs  = @[ hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan ];
    dan.prefs  = @[ ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi ];
    ed.prefs   = @[ jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay ];
    fred.prefs = @[ bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay ];
    gav.prefs  = @[ gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay ];
    hal.prefs  = @[ abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee ];
    ian.prefs  = @[ hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve ];
    jon.prefs  = @[ abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope ];
    abi.prefs  = @[ bob, fred, jon, gav, ian, abe, dan, ed, col, hal ];
    bea.prefs  = @[ bob, abe, col, fred, gav, dan, ian, ed, jon, hal ];
    cath.prefs = @[ fred, bob, ed, gav, hal, col, ian, abe, dan, jon ];
    dee.prefs  = @[ fred, jon, col, abe, ian, hal, gav, dan, bob, ed ];
    eve.prefs  = @[ jon, hal, fred, dan, abe, gav, col, ed, ian, bob ];
    fay.prefs  = @[ bob, abe, ed, ian, jon, dan, fred, gav, col, hal ];
    gay.prefs  = @[ jon, gav, hal, fred, bob, abe, col, ed, dan, ian ];
    hope.prefs = @[ gav, jon, bob, abe, ian, dan, hal, ed, col, fred ];
    ivy.prefs  = @[ ian, col, hal, gav, fred, bob, abe, ed, jon, dan ];
    jan.prefs  = @[ ed, hal, gav, abe, bob, jon, col, ian, fred, dan ];

    NSArray *men = abi.prefs;

    NSUInteger freeMenCount = men.count;
    while (freeMenCount > 0) {
        for (Person *guy in men) {
            if (guy.fiance == nil) {
                Person *gal = [guy nextCandidateNotYetProposedTo];
                if (gal.fiance == nil) {
                    [guy engageTo:gal];
                    freeMenCount--;
                } else if ([gal prefers:guy]) {
                    [guy engageTo:gal];
                }
            }
        }
    }

    for (Person *guy in men) {
        printf("%s is engaged to %s\n", [guy.name UTF8String], [guy.fiance.name UTF8String]);
    }
    printf("Stable = %d\n", (int)isStable(men));

    printf("\nSwitching fred & jon's partners\n");
    [fred engageTo:abi];
    [jon engageTo:bea];
    printf("Stable = %d\n", (int)isStable(men));
}

//--------------------------------------------------------------------

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        doMarriage();
    }
    return 0;
}

The code implements the Gale-Shapley algorithm to solve the Stable Marriage Problem. It takes as input a list of ten men and ten women along with their ranked preferences for each other. The code generates a stable set of engagements based on these preferences. It then perturbs this stable set to create an unstable set of engagements and checks the stability of this new set.


Works with: GNUstep only; not Cocoa
NSString *myString = @"The quick brown fox jumped over the lazy dog's back";
NSData *digest = [[myString dataUsingEncoding:NSUTF8StringEncoding] md5Digest]; // or another encoding of your choosing
NSLog(@"%@", [digest hexadecimalRepresentation]);

Works with: iPhone
Works with: Mac OS X
#import <CommonCrypto/CommonDigest.h>

NSString *myString = @"The quick brown fox jumped over the lazy dog's back";
NSData *data = [myString dataUsingEncoding:NSUTF8StringEncoding]; // or another encoding of your choosing
unsigned char digest[CC_MD5_DIGEST_LENGTH];
if (CC_MD5([data bytes], [data length], digest)) {
    NSMutableString *hex = [NSMutableString string];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [hex appendFormat: @"%02x", (int)(digest[i])];
    }
    NSLog(@"%@", hex);
}

Works with: Mac OS X (need to include "libcrypto.dylib" framework)
#include <openssl/md5.h>

NSString *myString = @"The quick brown fox jumped over the lazy dog's back";
NSData *data = [myString dataUsingEncoding:NSUTF8StringEncoding]; // or another encoding of your choosing
unsigned char digest[MD5_DIGEST_LENGTH];
if (MD5([data bytes], [data length], digest)) {
    NSMutableString *hex = [NSMutableString string];
    for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
        [hex appendFormat: @"%02x", (int)(digest[i])];
    }
    NSLog(@"%@", hex);
}

implement an MD5 encoding for a given string. The codes also include an optional validation using test values from IETF RFC (1321) for MD5. However, due to known weaknesses of MD5, alternatives like SHA-256 or SHA-3 are recommended for production-grade cryptography. If the solution is a library, refer to MD5/Implementation for a scratch implementation.


// declare the class to conform to NSStreamDelegate protocol

// in some method
NSOutputStream *oStream;
[NSStream getStreamsToHost:[NSHost hostWithName:@"localhost"] port:256 inputStream:NULL outputStream:&oStream];
[oStream setDelegate:self];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream open];

// later, in the same class:
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent {
    NSOutputStream *oStream = (NSOutputStream *)aStream;
    if (streamEvent == NSStreamEventHasBytesAvailable) {
        NSString *str = @"hello socket world";
        const char *rawstring = [str UTF8String];
        [oStream write:rawstring maxLength:strlen(rawstring)];
        [oStream close];
    }
}

opens a socket to localhost on port 256, sends the message "hello socket world", and then closes the socket. Error handling is not implemented.


[[[NSProcessInfo processInfo] environment] objectForKey:@"HOME"]

demonstrate how to retrieve a specific environment variable from the process's environment using the NSProcessInfo processInfo method in Unix systems. The variables that can be retrieved include PATH, HOME, and USER.