Transfered files over to Hugo
This commit is contained in:
parent
8197a7da63
commit
d851a3d320
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: PicoCTF - MOD 26
|
||||||
|
date: '2022-10-12 10:29:32 +0800'
|
||||||
|
categories: [CTF, PicoCTF]
|
||||||
|
tags: [ctf,picoctf]
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
Cryptography can be easy, do you know what ROT13 is?
|
||||||
|
|
||||||
|
The flag given: `cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_uJdSftmh}`
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
Using an [online tool](http://practicalcryptography.com/ciphers/rot13-cipher/) for ROT13, we can decode the message to get the flag.
|
||||||
|
|
||||||
|
Doing a ROT13 Decryption of `cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_uJdSftmh}`, I get the flag: `picoctf{next_time_i'll_try_2_rounds_of_rot13_hwqfsgzu}`
|
||||||
|
|
||||||
|
# Flag
|
||||||
|
|
||||||
|
```
|
||||||
|
picoctf{next_time_i'll_try_2_rounds_of_rot13_hwqfsgzu}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="flag.txt" }
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: PicoCTF - Obedient Cat
|
||||||
|
date: '2022-10-12 10:37:03 +0800'
|
||||||
|
categories: [CTF, PicoCTF]
|
||||||
|
tags: [ctf,picoctf]
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
This file has a flag in plain sight (aka "in-the-clear").
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
The flag was downloaded on a Windows machine (_probably not a good idea_), using notepad++ to view the file, the flag was found in the file.
|
||||||
|
|
||||||
|
However, using the `cat` command on a Linux machine, the flag should also be found.
|
||||||
|
|
||||||
|
# Flag
|
||||||
|
|
||||||
|
```
|
||||||
|
picoCTF{s4n1ty_v3r1f13d_1f6e3b3b}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="flag.txt" }
|
|
@ -0,0 +1,88 @@
|
||||||
|
---
|
||||||
|
title: HackerRank - Sum of Digits of a Five Digit Number
|
||||||
|
date: 2022-11-13 08:00:00
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, hackerrank] # TAG names should always be lowercase
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Given a five digit integer, print the sum of its digit
|
||||||
|
**Input**: 5 digit number, n
|
||||||
|
**Output**: sum of 5 digit number
|
||||||
|
|
||||||
|
## Input and Output Format
|
||||||
|
|
||||||
|
```
|
||||||
|
# Input
|
||||||
|
10564
|
||||||
|
|
||||||
|
# Output
|
||||||
|
16
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Sum Of Digits of a Five Digit Number.c" }
|
||||||
|
|
||||||
|
$1+0+5+6+4=16$
|
||||||
|
|
||||||
|
> This is a watered-down version of the question
|
||||||
|
> {: .prompt-info }
|
||||||
|
|
||||||
|
## Process
|
||||||
|
|
||||||
|
This was my thought process while attempting this challenge.
|
||||||
|
|
||||||
|
1. Calculate the number of digits
|
||||||
|
1. By dividing the number by 10 and incrementing a counter in a while loop
|
||||||
|
2. The number of digits can be found
|
||||||
|
2. In a for loop to loop through the total number of digits (5)
|
||||||
|
1. `sum += number % 10`
|
||||||
|
2. `number /= 10 `
|
||||||
|
1. This is to remove the LSB of the number for each iteration of the loop
|
||||||
|
3. Print out the sum
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
int n;
|
||||||
|
scanf("%d", &n);
|
||||||
|
//Complete the code to calculate the sum of the five digits on n.
|
||||||
|
int sum = 0, divisor=10, x = n;
|
||||||
|
if (n>=10000 && n <= 99999){
|
||||||
|
int noOfDigits = 0;
|
||||||
|
while (n!= 0){
|
||||||
|
n /= 10;
|
||||||
|
noOfDigits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i<= noOfDigits; i++){
|
||||||
|
sum += x % divisor;
|
||||||
|
x /= divisor;
|
||||||
|
}
|
||||||
|
printf("%d",sum);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Sum Of Digits of a Five Digit Number.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
I initially thought that I have to increment the mod divisor by 10 everytime (i.e. $10 \times 10 \times 10$) but soon realize that it is only going to make the number bigger.
|
||||||
|
|
||||||
|
I use the variable `n` to calculate the number of digits and used the same variable to calculate the sum, this gave me a result of 0 cuz `n` started from 0 in the loop!
|
||||||
|
|
||||||
|
I then realize I should probably initialize `sum` to 0 cuz any uninitialized number will be given garbage, this would screw up the sum of numbers.
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Exercism - Difference of Squares
|
||||||
|
date: '2022-11-18 18:35:51 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, exercism] # tag names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Find the difference between the square of the sum and the sum of the squares of the first n natural numbers.
|
||||||
|
|
||||||
|
The square of the sum of the first ten natural numbers is $(1 + 2 + ... + 10)^2 = 55^2 = 3025$.
|
||||||
|
|
||||||
|
The sum of the squares of the first ten natural numbers is $1^2 + 2^2 + ... + 10^2 = 385$.
|
||||||
|
|
||||||
|
Hence the difference between the square of the sum of the first ten natural numbers and the sum of the squares of the first ten natural numbers is $3025 - 385 = 2640$.
|
||||||
|
|
||||||
|
You are not expected to discover an efficient solution to this yourself from first principles; research is allowed, indeed, encouraged. finding the best algorithm for the problem is a key skill in software engineering.
|
||||||
|
|
||||||
|
> As referenced from [Exercism](https://exercism.org/tracks/c/exercises/difference-of-squares)
|
||||||
|
> {: .prompt-info }
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
This was a "fill in the blank" sort of question or "complete the function".
|
||||||
|
|
||||||
|
I first found the **sum of the squares of the numbers** from 1 to N.
|
||||||
|
Then I found the **square of the sum of the numbers** from 1 to N.
|
||||||
|
The function `difference_of_squares()` returns the **difference between the two numbers**.
|
||||||
|
|
||||||
|
Both sum functions are similar in that they use a while loop to loop through the numbers from 1 to number (N), decreasing N by 1 each iteration instead of using a for loop, which I was more comfortable. This is more
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "difference_of_squares.h"
|
||||||
|
#include <math.h>
|
||||||
|
unsigned int sum_of_squares(unsigned int number){
|
||||||
|
int sum = 0;
|
||||||
|
while (number > 0){
|
||||||
|
sum += pow(number,2);
|
||||||
|
number--;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
unsigned int square_of_sum(unsigned int number){
|
||||||
|
int sum = 0;
|
||||||
|
while (number > 0){
|
||||||
|
sum +=number;
|
||||||
|
number--;
|
||||||
|
}
|
||||||
|
return pow(sum, 2);
|
||||||
|
}
|
||||||
|
unsigned int difference_of_squares(unsigned int number){
|
||||||
|
int sumOfSquares = sum_of_squares(number);
|
||||||
|
int squareOfSum = square_of_sum(number);
|
||||||
|
return squareOfSum - sumOfSquares;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="difference_of_squares.c" }
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifndef DIFFERENCE_OF_SQUARES_H
|
||||||
|
#define DIFFERENCE_OF_SQUARES_H
|
||||||
|
unsigned int sum_of_squares(unsigned int number);
|
||||||
|
unsigned int square_of_sum(unsigned int number);
|
||||||
|
unsigned int difference_of_squares(unsigned int number);
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="difference_of_squares.h" }
|
||||||
|
|
||||||
|
# Conclusion
|
||||||
|
|
||||||
|
This was a good practice for while loops and function calls in C. I was able to use the `pow()` function to find the square of a number.
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Leetcode - Convert the temperature (2469)
|
||||||
|
date: '2022-11-18 20:51:00 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, leetcode] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
You are given a non-negative floating point number rounded to two decimal places celsius, that denotes the temperature in Celsius.
|
||||||
|
|
||||||
|
You should convert Celsius into Kelvin and Fahrenheit and return it as an array ans = [kelvin, fahrenheit].
|
||||||
|
|
||||||
|
Return the array ans. Answers within $10^{-5}$ of the actual answer will be accepted.
|
||||||
|
|
||||||
|
Note that:
|
||||||
|
|
||||||
|
Kelvin = Celsius + 273.15
|
||||||
|
|
||||||
|
Fahrenheit = Celsius \* 1.80 + 32.00
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```shell
|
||||||
|
Input: celsius = 36.50
|
||||||
|
Output: [309.65000,97.70000]
|
||||||
|
Explanation: Temperature at 36.50 Celsius converted in Kelvin is 309.65 and converted in Fahrenheit is 97.70.
|
||||||
|
```
|
||||||
|
|
||||||
|
# My thought process
|
||||||
|
|
||||||
|
I have no experience in creating arrays dynamically using `malloc` and had to look up how to do it.
|
||||||
|
|
||||||
|
This is one of the examples from the book I was reading - "The C Programming Language" by Brian Kernighan and Dennis Ritchie.
|
||||||
|
|
||||||
|
Here is what I've done:
|
||||||
|
|
||||||
|
1. I first created 2 variables of `double` data type to store the values of Kelvin and Fahrenheit.
|
||||||
|
2. Then I created a pointer to a double data type and allocated memory for it using `malloc`.
|
||||||
|
3. Using the Formula given, I calculated the values of Kelvin and Fahrenheit.
|
||||||
|
4. I assigned the value of 2 to the returnSize pointer
|
||||||
|
5. I then assigned the values of Kelvin and Fahrenheit to the array using the ans pointer.
|
||||||
|
6. Lastly, I returned the ans pointer.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
/**
|
||||||
|
* Note: The returned array must be malloced, assume caller calls free().
|
||||||
|
*/
|
||||||
|
double* convertTemperature(double celsius, int* returnSize){
|
||||||
|
double fah, kel;
|
||||||
|
double *ans = (double *) malloc(2 * sizeof(double));
|
||||||
|
|
||||||
|
kel = celsius + 273.15;
|
||||||
|
fah = celsius * 1.80 + 32.00;
|
||||||
|
|
||||||
|
|
||||||
|
*returnSize = 2;
|
||||||
|
|
||||||
|
ans[0] = kel;
|
||||||
|
ans[1] = fah;
|
||||||
|
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Convert the temperature.c" }
|
||||||
|
|
||||||
|
The malloc function creates a size of $2\times$ the size of a `double` data type to store both the values of Kelvin and Fahrenheit, this allows for dynamic allocation of memory.
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
This program could probably be improved by directly assigning the ans pointer to the values of Kelvin and Fahrenheit during the calculation. This would reduce the number of lines of code and reduce the memory usage as lesser variables are created.
|
||||||
|
|
||||||
|
I need to have a better understanding of `malloc` and its usage.
|
|
@ -0,0 +1,65 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Leetcode - Ugly Number(263)
|
||||||
|
date: '2022-11-18 21:23:39 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, leetcode] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Write a program to check whether a given number is an ugly number. Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.
|
||||||
|
|
||||||
|
Given an integer n, return true if n is an ugly number.
|
||||||
|
|
||||||
|
## Input and Output Format
|
||||||
|
|
||||||
|
```shell
|
||||||
|
Input: n = 6
|
||||||
|
Output: true
|
||||||
|
Explanation: 6 = 2 × 3
|
||||||
|
```
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
This was my thought process while attempting this challenge.
|
||||||
|
First, to return false if the number is less than 1. Next is to check if the number `n` is divisible by 2, 3 or 5, so, following the algorithm as I've done this in Python before, I created the function `keepDividingWhenDiviible()` to reduce the number based on its prime factors. I assigned `n` to the return value of the function that divides the number by 2, 3 or 5 and returned the condition that checks if the number is 1.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
bool isUgly(int n){
|
||||||
|
if (n<=0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
n = keepDividingWhenDivisible(n,2);
|
||||||
|
n = keepDividingWhenDivisible(n,3);
|
||||||
|
n = keepDividingWhenDivisible(n,5);
|
||||||
|
|
||||||
|
return (n==1) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int keepDividingWhenDivisible(int dividend, int divisor){
|
||||||
|
while (dividend % divisor == 0){
|
||||||
|
dividend /= divisor;
|
||||||
|
}
|
||||||
|
return dividend;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Ugly Number.c" }
|
||||||
|
|
||||||
|
Honestly, I realized that I was reading through the algorithm explanation on leetcode but didn't realize that I wasn't reading the description, I've created the function accordingly as I've done this using python in the past.
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
1. The function that assigned `n` could be reduced to a loop, this is one way to improve the code.
|
||||||
|
2. I initially thought that the algorithm wanted to create a recursive function to check if the number is divisible by 2, 3 or 5. But instead, the easier and more efficient way is to constantly check the remainder of the arithmetic operation and divide the number by the divisor until the remainder is not 0.
|
||||||
|
3. I wanted to use a ternary operator to return the condition that checks if the number is 1, but I realized that it would just not be useful as the check will just return its corrosponding boolean value and there was no point in using a ternary operator.
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: PicoCTF - Wave a flag
|
||||||
|
date: '2022-10-12 10:37:00 +0800'
|
||||||
|
categories: [CTF, PicoCTF]
|
||||||
|
tags: [ctf,picoctf]
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
Can you invoke help flags for a tool or binary? [This program](https://mercury.picoctf.net/static/1b1b6b2b4b3b4b3b4b3b4b3b4b3b4b3b/warm) has extraordinarily helpful information...
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
{: width="972" height="589" }
|
||||||
|
_Hex Editor in VSCode_
|
||||||
|
|
||||||
|
The flag is found in the file, but it is not in plain sight. Using a hex editor, the flag can be found.
|
||||||
|
The word binary triggered me to use some sort of hex editor to view the file. I used VSCode to view the file, and found the flag.
|
||||||
|
|
||||||
|
# Flag
|
||||||
|
|
||||||
|
```
|
||||||
|
picoCTF{b1scu1ts_4nd_gr4vy_6635aa47}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="flag.txt" }
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: HackerRank - Printing Tokens
|
||||||
|
date: '2022-11-19 10:15:33 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, hackerrank] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Given a sentence, `s`, print each word of the sentence in a new line.
|
||||||
|
|
||||||
|
## Input and Output Format
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Input:
|
||||||
|
This is C
|
||||||
|
|
||||||
|
# Output:
|
||||||
|
This
|
||||||
|
is
|
||||||
|
C
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Input and Output" }
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
This was a pretty simple challenge. Completing the code, I've added a for loop to print each character at a time, scanning for any blank spaces and "replacing" that with a newline escape character `\n`.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
char *s;
|
||||||
|
s = malloc(1024 * sizeof(char));
|
||||||
|
scanf("%[^\n]", s);
|
||||||
|
s = realloc(s, strlen(s) + 1);
|
||||||
|
//Write your logic to print the tokens of the sentence here.
|
||||||
|
for (int i = 0;i <strlen(s); i++){
|
||||||
|
//if(s[i] != ' '){
|
||||||
|
// printf("%c", s[i]);
|
||||||
|
//}
|
||||||
|
//else{
|
||||||
|
// printf("\n");
|
||||||
|
//}
|
||||||
|
(s[i] != ' ') ? printf("%c", s[i]) : printf("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Printing Tokens.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
Looping through each character in the string, a check is done to check for blankspaces and replacing them with a newline character.
|
||||||
|
|
||||||
|
I did it using an ordinary for loop but translated that same loop to a ternery operator for elegance. I really like the use of ternery operators in C.
|
||||||
|
|
||||||
|
This challenge earned me 20 points!
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: HackerRank - Sherlock and Divisors
|
||||||
|
date: '2022-11-19 11:33:55 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, hackerrank] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Watson gives an integer `N` to Sherlock and asks him: What is the number of divisors of `N` that are divisible by `2`?
|
||||||
|
|
||||||
|
## Input and Output Format
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Input:
|
||||||
|
2
|
||||||
|
9
|
||||||
|
8
|
||||||
|
|
||||||
|
# Output:
|
||||||
|
0
|
||||||
|
3
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Input and Output" }
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
9 has three divisors 1, 3 and 9 none of which is divisible by 2.
|
||||||
|
8 has four divisors 1,2,4 and 8, out of which three are divisible by 2.
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
I thought that this is one of the easier ones to do, I first did a while loop to loop through all the numbers from 1 to `N` and check if it is divisible by 2. If it is, I increment a counter. I then print the counter. This only worked for the first test case. I then did a for loop to loop through all the numbers from 1 to `N` and check if it is divisible by 2. But this was a code that was not optimized for HackerRank's tests and failed some test cases.
|
||||||
|
|
||||||
|
I then loop through numbers from 1 to square root of `n` as the divisors of `n` are always less than or equal to the square root of `n`.
|
||||||
|
|
||||||
|
1. I first checked that `i` is divisible by `n`.
|
||||||
|
2. I then check if the number `i` is divisible by 2 and increment the counter if it is.
|
||||||
|
3. Next, I checked if `n/i` is divisible by 2 and increment the counter if it is.
|
||||||
|
4. THe last statement is to remove the number `n` if it is divisible by 2 as it is a duplicate.
|
||||||
|
|
||||||
|
This code was after some trial and error and multiple references.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
int divisors(int n) {
|
||||||
|
int count = 0;
|
||||||
|
for (int i=1;i<=sqrt(n);i++)
|
||||||
|
{
|
||||||
|
if (n%i==0)
|
||||||
|
{
|
||||||
|
count = (i%2==0) ? count + 1 : count;
|
||||||
|
count = ((n/i)%2==0) ? count + 1 : count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((n%2==0) && (pow((int)sqrt(n), 2) == n))
|
||||||
|
count--;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="divisors.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
Math theory was very important and applicable to this challlenge, the fact that the divisors of `n` are always less than or equal to the square root of `n` was very important. This is also one of the ways to check if the number is a prime doing a prime factorization from 1 to the square root of the number.
|
||||||
|
|
||||||
|
This is an interesting challenge that made me apply my math knowledge learnt.
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Leetcode - Concatenation of array(1929)
|
||||||
|
date: '2022-11-19 08:43:07 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, leetcode] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Given an integer array nums of length n, you want to create an array ans of length 2n where ans[i] == nums[i] and ans[i + n] == nums[i] for 0 <= i < n (0-indexed).
|
||||||
|
|
||||||
|
Specifically, ans is the concatenation of two nums arrays.
|
||||||
|
|
||||||
|
Return the array ans.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```shell
|
||||||
|
Input: nums = [1,2,1]
|
||||||
|
Output: [1,2,1,1,2,1]
|
||||||
|
Explanation: The array ans is formed as follows:
|
||||||
|
- ans = [nums[0],nums[1],nums[2],nums[0],nums[1],nums[2]]
|
||||||
|
- ans = [1,2,1,1,2,1]
|
||||||
|
```
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
This was a pretty simple one other that figuring out how to use `malloc` again. This would be much simpler to do in python.
|
||||||
|
|
||||||
|
After creating an array with size dynamically allocated to `2n` where `n` is the size of the input array, I've managd to follow the description and concatenate the array using a for loop.
|
||||||
|
|
||||||
|
There should probably be a more elegant and efficient way to do this, but I'll still need to learn more about pointers and arrays.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
/**
|
||||||
|
* Note: The returned array must be malloced, assume caller calls free().
|
||||||
|
*/
|
||||||
|
int* getConcatenation(int* nums, int numsSize, int* returnSize){
|
||||||
|
//int n = (sizeof(nums)/sizeof(int));
|
||||||
|
int *ans = (int *)malloc(2 * numsSize * sizeof(int));
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i<numsSize; i++){
|
||||||
|
ans[i] = nums[i];
|
||||||
|
ans[i+numsSize] = nums[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
*returnSize = 2 * numsSize;
|
||||||
|
return ans;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Concatenation of array.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
1. I initially thought of getting the size "dynamically" by using `sizeof(nums)/sizeof(int)` but I instead realize that I should just use the input parameter `numsSize` instead. However, I'm leaving it in the code as a comment for future reference.
|
||||||
|
|
||||||
|
2. I also had trouble with the second perimeter of the for loop, I used `i+2*numsSize` but I realized that I should just use `numsSize` instead as I didn't really have to loop through an empty array towards the end. So, looping through the array once with `i<numsSize` is enough to insert the values in position `i` and `i+numsSize`.
|
||||||
|
|
||||||
|
3. I didn't know that I should use all the input parameters and had a _heap buffer overflow error_ until I added the `*returnSize = 2 * numsSize;` line as it is used to return the size of the array.
|
||||||
|
|
||||||
|
I'm still pretty new to the leetcode ecosystem and have to do more practices to truly understand the proper way of attempting the questions.
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Leetcode - Two Sums(1)
|
||||||
|
date: '2022-11-19 15:01:45 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, leetcode] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
|
||||||
|
|
||||||
|
You may assume that each input would have exactly one solution, and you may not use the same element twice.
|
||||||
|
|
||||||
|
You can return the answer in any order.
|
||||||
|
|
||||||
|
# Input and Output
|
||||||
|
|
||||||
|
```shell
|
||||||
|
Input: nums = [2,7,11,15], target = 9
|
||||||
|
Output: [0,1]
|
||||||
|
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
|
||||||
|
```
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
Saw guy doing it in [Assembly](https://www.youtube.com/watch?v=lALPErFlfNQ) but wanted to do it myself before watching the video so that I can understand it better.
|
||||||
|
|
||||||
|
Since the assumption is that there is only one solution, I can just brute force it by using two for loops. The first loop will be the first number and the second loop will be the second number. If the sum of the two numbers is equal to the target, then I can return the indices of the two numbers.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
/**
|
||||||
|
* Note: The returned array must be malloced, assume caller calls free().
|
||||||
|
*/
|
||||||
|
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
|
||||||
|
int *sums = (int *)malloc(numsSize * sizeof(int));
|
||||||
|
int i, j, firstNum;
|
||||||
|
*returnSize = 2;
|
||||||
|
|
||||||
|
for(i = 0; i< numsSize; i++){
|
||||||
|
firstNum = nums[i];
|
||||||
|
int x = target - firstNum;
|
||||||
|
for (j = i + 1; j<numsSize ; j++){
|
||||||
|
if (nums[j] == x){
|
||||||
|
sums[0] = i;
|
||||||
|
sums[1] = j;
|
||||||
|
return sums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Two Sums.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
1. Using a nested for loop, I first get the first number and assume that the second number is the difference between the target and the first number.
|
||||||
|
2. I subtracted the first number from the target and used a second for loop to find the position of the second number in the array.
|
||||||
|
3. I then assign the indexes to the sums array and return the array.
|
||||||
|
|
||||||
|
This is an "easy" challenge but I think the solution could be more elegant than just plain brute force. I'll try to think of a better solution later. This solution took $99 ms$ and $6.2MB$ of memory, which was still pretty fast and memory efficient.
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: HackerRank - Handshake
|
||||||
|
date: '2022-11-20 15:35:37 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, hackerrank,math] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
At the annual meeting of Board of Directors of Acme Inc. If everyone attending shakes hands exactly one time with every other attendee, how many handshakes are there?
|
||||||
|
|
||||||
|
## Input and Output Format
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Input:
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
# Output:
|
||||||
|
0
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Input and Output" }
|
||||||
|
|
||||||
|
## Process
|
||||||
|
|
||||||
|
This is a math challenge. So using the primitive way of counting, I counted the number of handshakes for each number of attendees, I came up with this:
|
||||||
|
|
||||||
|
```
|
||||||
|
n = 1 2 3 4 5
|
||||||
|
HS = 0 1 3 6 10
|
||||||
|
```
|
||||||
|
|
||||||
|
where `HS` is the number of handshakes.
|
||||||
|
|
||||||
|
So, the interval between each number of handshake is `1, 2, 3, 4, 5`. With this, I was able to come up with a simple formula to calculate the number of handshakes with respect to the number of attendees `n`:
|
||||||
|
|
||||||
|
$$
|
||||||
|
HS_n = \frac{n(n-1)}{2}
|
||||||
|
$$
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
This formula could be use as the return value of the function `int numberOfHandshakes(int n)`, shown below.
|
||||||
|
|
||||||
|
```c
|
||||||
|
int handshake(int n) {
|
||||||
|
return n*(n-1)/2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Handshake.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
This is a pretty simple challenge that allows me to practice sequence counting, I was able to apply what I've learnt in this challenge.
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: 'HackerRank - Project Euler #1: Multiples of 3 and 5'
|
||||||
|
date: '2022-11-20 16:15:33 +0800'
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, hackerrank,math,projecteuler] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
|
||||||
|
Find the sum of all the multiples of 3 or 5 below N.
|
||||||
|
|
||||||
|
## Input and Output Format
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Input:
|
||||||
|
2
|
||||||
|
10
|
||||||
|
100
|
||||||
|
# Output:
|
||||||
|
23
|
||||||
|
2318
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Input and Output" }
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
For N = 10, if we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
|
||||||
|
Similarly for N = 100, we get 2318.
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
Using a for loop to loop through all the numbers below N, and check if the number is a multiple of 3 or 5, if it is, add it to the sum, and print out the sum at the end of the loop.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void sumMultiple(int n);
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int t;
|
||||||
|
scanf("%d",&t);
|
||||||
|
for(int a0 = 0; a0 < t; a0++){
|
||||||
|
int n;
|
||||||
|
scanf("%d",&n);
|
||||||
|
sumMultiple(n);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sumMultiple(int n){
|
||||||
|
int sum = 0;
|
||||||
|
for(int i = 1; i< n; i++){
|
||||||
|
if(i%3 == 0 || i% 5 == 0){
|
||||||
|
sum += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("%d", sum);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Multiples of 3 and 5.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
This solution was a bit of a brute force solution, but it worked. It passed `4/6` test cases and needed to be optimized. I'm sure there's a more efficient way to do this, but I'll take a second look at this later.
|
||||||
|
|
||||||
|
# References
|
||||||
|
|
||||||
|
- [HackerRank - Project Euler #1: Multiples of 3 and 5](https://www.hackerrank.com/contests/projecteuler/challenges/euler001/problem)
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: HackerRank - Minimum Height Triangle
|
||||||
|
date: "2022-11-21 17:19:32 +0800"
|
||||||
|
categories: [Code, C]
|
||||||
|
tags: [c, hackerrank, math] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Given integers `b` and `a`, find the smallest integer `h`, such that there exists a triangle of height `h`, base `b`, having an area of at least `a`.
|
||||||
|
|
||||||
|
## Example Input Output
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Input:
|
||||||
|
2 2
|
||||||
|
# Output:
|
||||||
|
2
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Input and Output" }
|
||||||
|
|
||||||
|
Explanation:
|
||||||
|
The task is to find the height of the triangle having base `b = 2` and area `a = 2`. It turns out that the height is `h = 2`.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Input:
|
||||||
|
17 100
|
||||||
|
# Output:
|
||||||
|
12
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Input and Output" }
|
||||||
|
|
||||||
|
Explanation:
|
||||||
|
The task is to find the height of the triangle having base `b = 17` and area `a = 100`. It turns out that the height is `h = 12` and the triangle has an area of `102`.
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
The area of a triangle is given by the formula:
|
||||||
|
|
||||||
|
$$
|
||||||
|
A = \frac{1}{2}bh
|
||||||
|
$$
|
||||||
|
|
||||||
|
where `b` is the base and `h` is the height of the triangle. Manupulating the formula, we get:
|
||||||
|
|
||||||
|
$$
|
||||||
|
h = \frac{2A}{b}
|
||||||
|
$$
|
||||||
|
|
||||||
|
I knew I needed to use the ceiling function to get the smallest integer `h` that satisfies the condition. So I used the `ceil()` function from the `math.h` library to round the calculated value of the height up to the next integer. The formula can be changed to:
|
||||||
|
|
||||||
|
$$
|
||||||
|
h = \lceil\frac{2A}{b} \rceil
|
||||||
|
$$
|
||||||
|
|
||||||
|
We are able to use this formula to calculate the height of the triangle given the base and area.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
int lowestTriangle(int trianglebase, int area) {
|
||||||
|
double height = ceil(2 * (double)area / (double)trianglebase);
|
||||||
|
return (int)height;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Minimum Height Triangle.c" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
Upon applying the manipulated formula, I was able to return the minimum height of the triangle, given the base and the area.
|
||||||
|
|
||||||
|
However, All challenges come with their hurdles and I was met with some when I did this.
|
||||||
|
|
||||||
|
1. I initially used `int` for the height, but using a calculator to check the results, some results return a decimal value and `int` will truncate the decimal value. So, I changed the type to `double` and used `ceil()` to round up the value.
|
||||||
|
2. I needed to typecast the `area` and `trianglebase` to `double` to avoid integer division as the result of the division will be an integer.
|
||||||
|
3. The return value of the function is an `int`, so I had to typecast the `height` to `int`.
|
||||||
|
|
||||||
|
This solution passed all testcases.
|
|
@ -0,0 +1,144 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: The Factorial Function
|
||||||
|
date: '2022-11-21 16:03:48 +0800'
|
||||||
|
categories: [Code]
|
||||||
|
tags: [c,python,math] # TAG names should always be lowercase
|
||||||
|
math: true
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
---
|
||||||
|
|
||||||
|
# The Factorial Function
|
||||||
|
|
||||||
|
The factorial function is a mathematical function that takes a non-negative integer `n` and returns the product of all positive integers less than or equal to `n`. The factorial function is denoted by `n!`.
|
||||||
|
|
||||||
|
This is a reference page for the factorial function, written in C and Python.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
The first 10 factorials are:
|
||||||
|
|
||||||
|
| n | n! |
|
||||||
|
| --- | ------- |
|
||||||
|
| 0 | 1 |
|
||||||
|
| 1 | 1 |
|
||||||
|
| 2 | 2 |
|
||||||
|
| 3 | 6 |
|
||||||
|
| 4 | 24 |
|
||||||
|
| 5 | 120 |
|
||||||
|
| 6 | 720 |
|
||||||
|
| 7 | 5040 |
|
||||||
|
| 8 | 40320 |
|
||||||
|
| 9 | 362880 |
|
||||||
|
| 10 | 3628800 |
|
||||||
|
|
||||||
|
Where $n!=n\times(n-1)\times(n-2)\times\cdots\times2\times1$ and $n! = n\times(n-1)!$.
|
||||||
|
|
||||||
|
The [Wikipedia page](https://en.wikipedia.org/wiki/Factorial) has a more detailed explanation of the factorial function.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
## Psuedocode
|
||||||
|
|
||||||
|
This is the psuedocode for the factorial function:
|
||||||
|
|
||||||
|
```
|
||||||
|
FUNCTION factorial(n)
|
||||||
|
IF n = 0
|
||||||
|
RETURN 1
|
||||||
|
ELSE
|
||||||
|
RETURN n * factorial(n-1)
|
||||||
|
END IF
|
||||||
|
END FUNCTION
|
||||||
|
```
|
||||||
|
|
||||||
|
## Factorial in C
|
||||||
|
|
||||||
|
This is a sample factorial function that gets the user's input and returns the factorial of the input, written in C.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main();
|
||||||
|
int factorial(int n);
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int n;
|
||||||
|
printf("Enter a number: ");
|
||||||
|
scanf("%d", &n);
|
||||||
|
int fac = factorial(n);
|
||||||
|
printf("\nThe factorial of %d is %d.", n, fac);
|
||||||
|
}
|
||||||
|
|
||||||
|
int factorial(int n){
|
||||||
|
if(n == 0 || n == 1){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return(n* factorial(n-1));
|
||||||
|
}
|
||||||
|
//return (n == 0) ? 1 : (n * factorial(n-1));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Factorial.c" }
|
||||||
|
|
||||||
|
```shell
|
||||||
|
Enter a number: 9
|
||||||
|
|
||||||
|
The factorial of 9 is 362880.
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Factorial.c Input and Output" }
|
||||||
|
|
||||||
|
The recursive factorial function could be simplified to a single line of code:
|
||||||
|
|
||||||
|
```c
|
||||||
|
return (n == 0) ? 1 : (n * factorial(n-1));
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Factorial With Ternary Operator" }
|
||||||
|
|
||||||
|
This returns 1 if `n` is 0, otherwise it recursively returns `n` multiplied by the factorial of `n-1`.
|
||||||
|
|
||||||
|
I really like the use and elegance of Ternary Operators in C.
|
||||||
|
|
||||||
|
## Factorial in Python
|
||||||
|
|
||||||
|
This is the same factorial function written in Python.
|
||||||
|
|
||||||
|
```python
|
||||||
|
def factorial(x):
|
||||||
|
if (x == 0):
|
||||||
|
return (1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return (x * factorial(x - 1))
|
||||||
|
|
||||||
|
# return (1 if x == 0 else x * factorial(x - 1))
|
||||||
|
|
||||||
|
num = int(input("Please Enter a number: "))
|
||||||
|
print("Factorial: ",str(factorial(num)))
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Factorial.py" }
|
||||||
|
|
||||||
|
```shell
|
||||||
|
Please Enter a number: 9
|
||||||
|
Factorial: 362880
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Factorial.py Input and Output" }
|
||||||
|
|
||||||
|
```python
|
||||||
|
def factorial(x):
|
||||||
|
return (1 if x == 0 else x * factorial(x - 1))
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Factorial.py" }
|
||||||
|
|
||||||
|
Similar to the [C Version](#factorial-in-c), the Python version could be simplified to a single line of code.
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: ARM Assembly - Hello World!
|
||||||
|
date: '2022-12-02 08:49:07 +0800'
|
||||||
|
categories: [Code, ArmAssembly]
|
||||||
|
tags: [code, arm, assembly, armassembly] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
math: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
I'm using WSL to build and run the ARM assembly code, these are the installation packages I used:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install gcc-arm-linux-gnueabi make git-core ncurses-dev qemu qemu-user
|
||||||
|
```
|
||||||
|
|
||||||
|
{:file="Installation on Windows WSL"}
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
## Simple program to return a number to shell
|
||||||
|
|
||||||
|
```armasm
|
||||||
|
.global _start
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
mov r7, #0x1 @ System call number for exit (0x1)
|
||||||
|
mov r0, #32 @ Exit code 32 (Returns 32 to the shell)
|
||||||
|
swi 0 @ Software interrupt
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
```
|
||||||
|
|
||||||
|
{:file="test.s"}
|
||||||
|
|
||||||
|
This returns
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo $?
|
||||||
|
32
|
||||||
|
```
|
||||||
|
|
||||||
|
{:file="Shell output"}
|
||||||
|
|
||||||
|
The `echo $?` command returns the exit code of the last command.
|
||||||
|
|
||||||
|
The ARM systemcall table is available [here](https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md#arm-32_bit_EABI). I've used the `exit` system call, which is `0x1`.
|
||||||
|
|
||||||
|
## Hello World
|
||||||
|
|
||||||
|
```armasm
|
||||||
|
.global _start
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
mov r7, #0x4 @ System call number for write (0x4)
|
||||||
|
mov r0, #0x1 @ File descriptor (stdout)
|
||||||
|
|
||||||
|
ldr r1, =message @ Load address of message into r1
|
||||||
|
ldr r2, =len @ Load length of message into r2
|
||||||
|
swi 0 @ Software interrupt
|
||||||
|
|
||||||
|
mov r7, #0x1 @ System call number for exit (0x1)
|
||||||
|
swi 0 @ Software interrupt
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
message:
|
||||||
|
.ascii "Welcome to DevBlog!\n"
|
||||||
|
|
||||||
|
len = . - message @ Length of message
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
{:file="armasm.s"}
|
||||||
|
|
||||||
|
This returns
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ qemu-arm ./armasm.elf
|
||||||
|
Welcome to DevBlog!
|
||||||
|
```
|
||||||
|
|
||||||
|
{:file="Shell output"}
|
||||||
|
|
||||||
|
The `swi` instruction is a software interrupt instruction that allows the program to call the kernel, where it will use register `r7` to determine which system call to use and registers `r0` to `r4` to pass parameters to the system call.
|
||||||
|
|
||||||
|
Using the system call table, loading `0x4` into `r7` calls the `write` system call.
|
||||||
|
|
||||||
|
The `write` system call takes 3 arguments:
|
||||||
|
|
||||||
|
- `r0` is the [file descriptor](#file-descriptors) for STDOUT (1)
|
||||||
|
- `r1` is the address of the message
|
||||||
|
- `r2` is the length of the message.
|
||||||
|
|
||||||
|
Loading the address of the message into `r1` and the length of the message into `r2` is done using the `ldr` instruction and `r0` is loaded with the [file descriptor](#file-descriptors) 1 for `STDOUT`. This directly outputs the message to STDOUT.
|
||||||
|
|
||||||
|
## File Descriptors
|
||||||
|
|
||||||
|
These are the file descriptors for the standard input, output and error:
|
||||||
|
|
||||||
|
| File Descriptor | Description |
|
||||||
|
| --------------- | ----------- |
|
||||||
|
| 0 | STDIN |
|
||||||
|
| 1 | STDOUT |
|
||||||
|
| 2 | STDERR |
|
||||||
|
|
||||||
|
# Compilation
|
||||||
|
|
||||||
|
To compile the code(s), I'm using the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
arm-linux-gnueabi-as armasm.s -o armasm.o
|
||||||
|
arm-linux-gnueabi-gcc-9 armasm.o -o armasm.elf -nostdlib
|
||||||
|
```
|
||||||
|
|
||||||
|
{:file="Compilation"}
|
||||||
|
|
||||||
|
The `arm-linux-gnueabi-as` command compiles the assembly code into an object file, which is then linked with the `arm-linux-gnueabi-gcc-9` command to create an executable file.
|
||||||
|
|
||||||
|
The `-nostdlib` flag is used to prevent the compiler from linking the [standard libraries](https://en.wikipedia.org/wiki/C_standard_library), which is not needed for this program.
|
||||||
|
|
||||||
|
## Makefile
|
||||||
|
|
||||||
|
Alternatively, you can use a `Makefile` to compile the code(s):
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
CFLAGS = -nostdlib
|
||||||
|
NAME = armasm
|
||||||
|
|
||||||
|
$(NAME): $(NAME).o
|
||||||
|
arm-linux-gnueabi-gcc-9 $(NAME).o -o $(NAME).elf $(CFLAGS)
|
||||||
|
|
||||||
|
$(NAME).o: $(NAME).s
|
||||||
|
arm-linux-gnueabi-as $(NAME).s -o $(NAME).o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows you to compile the code(s) using the command `make` and clean the object files using the command `make clean`.
|
||||||
|
|
||||||
|
# Running
|
||||||
|
|
||||||
|
To run the code, I'm using the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
qemu-arm ./armasm.elf
|
||||||
|
```
|
||||||
|
|
||||||
|
Using the qemu emulator, you can run the code on your computer without having to use a Raspberry Pi or other ARM device.
|
||||||
|
|
||||||
|
# References
|
||||||
|
|
||||||
|
- [ARM System Call Table](https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md#arm-32_bit_EABI)
|
||||||
|
- This Wonderful [Tutorial](https://www.youtube.com/watch?v=FV6P5eRmMh8)
|
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Leetcode - Build Array From Permutation (1920)
|
||||||
|
date: "2023-02-11 08:02:32 +0800"
|
||||||
|
categories: [Code, Java]
|
||||||
|
tags: [java] # TAG names should always be lowercase
|
||||||
|
author: devoalda
|
||||||
|
math: true
|
||||||
|
libraries:
|
||||||
|
- mathjax
|
||||||
|
---
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
Given a zero-based permutation nums (0-indexed), build an array ans of the same length where ans[i] = nums[nums[i]] for each 0 <= i < nums.length and return it.
|
||||||
|
|
||||||
|
A zero-based permutation nums is an array of distinct integers from 0 to nums.length - 1 (inclusive).
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```python
|
||||||
|
Input: nums = [0,2,1,5,3,4]
|
||||||
|
Output: [0,1,2,4,5,3]
|
||||||
|
Explanation: The array ans is built as follows:
|
||||||
|
ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]]
|
||||||
|
= [nums[0], nums[2], nums[1], nums[5], nums[3], nums[4]]
|
||||||
|
= [0,1,2,4,5,3]
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Input/Output"}
|
||||||
|
|
||||||
|
# Thought Process
|
||||||
|
|
||||||
|
Simple Brute force method that requires $O(n)$ time and space complexity.\\
|
||||||
|
|
||||||
|
Using the explanation, Ive created a new array (`ans`) and assigned the elements of `ans` with the corrosponding
|
||||||
|
values from `nums[nums[i]]`, where i is the index of the for loop.
|
||||||
|
|
||||||
|
# Code
|
||||||
|
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
public int[] buildArray(int[] nums) {
|
||||||
|
int[] ans = new int[nums.length];
|
||||||
|
|
||||||
|
for(int i = 0; i < nums.length; i++){
|
||||||
|
ans[i] = nums[nums[i]];
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{: file="Solution.java" }
|
||||||
|
|
||||||
|
# Afterthoughts
|
||||||
|
|
||||||
|
This could be improved to $O(1)$ time and space complexity but I need more experience with data structures
|
||||||
|
and algorithms. This is also my first Java leetcode attempt.
|
Loading…
Reference in New Issue