add AdventOfCodeDay2 test
This commit is contained in:
parent
b266c6b4d3
commit
3791a78e19
@ -120,6 +120,10 @@ struct class_entry * class_resolver_lookup_class(int class_hash_table_length,
|
||||
const uint8_t * class_name,
|
||||
int class_name_length)
|
||||
{
|
||||
printf("class_resolver_lookup_class: ");
|
||||
for (int i = 0; i < class_name_length; i++) { fputc(class_name[i], stdout); }
|
||||
fputc('\n', stdout);
|
||||
|
||||
struct hash_table_entry * e = hash_table_find(class_hash_table_length,
|
||||
class_hash_table,
|
||||
class_name,
|
||||
@ -134,6 +138,10 @@ struct field_entry * class_resolver_lookup_field(struct class_entry * class_entr
|
||||
const uint8_t * field_name,
|
||||
int field_name_length)
|
||||
{
|
||||
printf("class_resolver_lookup_field: ");
|
||||
for (int i = 0; i < field_name_length; i++) { fputc(field_name[i], stdout); }
|
||||
fputc('\n', stdout);
|
||||
|
||||
int fields_hash_table_length = class_entry->fields.length;
|
||||
struct hash_table_entry * fields_hash_table = class_entry->fields.entry;
|
||||
|
||||
@ -150,6 +158,10 @@ struct method_info * class_resolver_lookup_method(struct class_entry * class_ent
|
||||
const uint8_t * method_name,
|
||||
int method_name_length)
|
||||
{
|
||||
printf("class_resolver_lookup_method: ");
|
||||
for (int i = 0; i < method_name_length; i++) { fputc(method_name[i], stdout); }
|
||||
fputc('\n', stdout);
|
||||
|
||||
int methods_hash_table_length = class_entry->methods.length;
|
||||
struct hash_table_entry * methods_hash_table = class_entry->methods.entry;
|
||||
|
||||
|
23
c/execute.c
23
c/execute.c
@ -75,7 +75,6 @@ void op_astore(struct vm * vm, uint32_t index)
|
||||
|
||||
void op_astore_0(struct vm * vm)
|
||||
{
|
||||
printf("op_astore0 %d\n", vm->current_frame->operand_stack_ix);
|
||||
uint32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
vm->current_frame->local_variable[0] = value;
|
||||
}
|
||||
@ -959,14 +958,28 @@ void op_ireturn(struct vm * vm)
|
||||
of the invoked method was boolean, then value is narrowed from int to
|
||||
boolean by taking the bitwise AND of value and 1. */
|
||||
|
||||
uint32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
// The current method must have return type boolean, byte, char, short, or int
|
||||
|
||||
int32_t value = operand_stack_pop_u32(vm->current_frame);
|
||||
switch (vm->current_frame->return_type) {
|
||||
case 'I':
|
||||
case 'Z': // boolean
|
||||
value = value & 1;
|
||||
break;
|
||||
case 'B': // byte
|
||||
value = (int8_t)value;
|
||||
break;
|
||||
case 'C': // char
|
||||
value = (uint16_t)value;
|
||||
break;
|
||||
case 'S': // short
|
||||
value = (int16_t)value;
|
||||
break;
|
||||
case 'I': // int
|
||||
value = (int32_t)value;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "conversion not implemented: %c\n", vm->current_frame->return_type);
|
||||
fprintf(stderr, "invalid conversion: %c\n", vm->current_frame->return_type);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
operand_stack_push_u32(vm->current_frame, value);
|
||||
|
||||
|
44
c/frame.c
44
c/frame.c
@ -73,12 +73,17 @@ static int descriptor_nargs(struct constant * descriptor_constant)
|
||||
assert(descriptor_constant->utf8.length >= 2);
|
||||
assert(descriptor_constant->utf8.bytes[0] == '(');
|
||||
|
||||
printf("method descriptor: ");
|
||||
print_utf8_string(descriptor_constant);
|
||||
printf("\n");
|
||||
|
||||
int i = 1;
|
||||
int nargs = 0;
|
||||
while (i < descriptor_constant->utf8.length) {
|
||||
if (descriptor_constant->utf8.bytes[i] == ')')
|
||||
break;
|
||||
nargs += 1;
|
||||
if (descriptor_constant->utf8.bytes[i] != '[')
|
||||
nargs += 1;
|
||||
i += 1;
|
||||
}
|
||||
assert(i + 2 == descriptor_constant->utf8.length);
|
||||
@ -100,7 +105,6 @@ void vm_static_method_call(struct vm * vm, struct class_file * class_file, struc
|
||||
|
||||
int code_name_index = find_code_name_index(class_file);
|
||||
assert(code_name_index > 0);
|
||||
printf("code_name_index %d\n", code_name_index);
|
||||
|
||||
struct Code_attribute * code = get_code_attribute(code_name_index,
|
||||
method_info->attributes_count,
|
||||
@ -120,9 +124,10 @@ void vm_static_method_call(struct vm * vm, struct class_file * class_file, struc
|
||||
printf("nargs %d\n", nargs);
|
||||
for (int i = 0; i < nargs; i++) {
|
||||
uint32_t value = operand_stack_pop_u32(old_frame);
|
||||
printf("local[%d] = %x\n", nargs - i - 1, value);
|
||||
vm->current_frame->local_variable[nargs - i - 1] = value;
|
||||
}
|
||||
vm->current_frame->return_type = descriptor_constant->utf8.bytes[nargs + 2];
|
||||
vm->current_frame->return_type = descriptor_constant->utf8.bytes[descriptor_constant->utf8.length - 1];
|
||||
|
||||
vm->current_frame->pc = 0;
|
||||
vm->current_thread.current_class = class_file;
|
||||
@ -140,9 +145,38 @@ void vm_method_return(struct vm * vm)
|
||||
assert(vm->current_frame != old_frame);
|
||||
vm->current_frame->pc = vm->current_frame->next_pc;
|
||||
|
||||
/*
|
||||
boolean int 1
|
||||
byte int 1
|
||||
char int 1
|
||||
short int 1
|
||||
int int 1
|
||||
float float 1
|
||||
reference reference 1
|
||||
returnAddress returnAddress 1
|
||||
long long 2
|
||||
double double 2
|
||||
*/
|
||||
/*
|
||||
B byte
|
||||
C char
|
||||
D double
|
||||
F float
|
||||
I int
|
||||
J long
|
||||
L ClassName ; Named class or interface type
|
||||
S short
|
||||
Z boolean
|
||||
[ ComponentType Array of given component type
|
||||
*/
|
||||
|
||||
switch (old_frame->return_type) {
|
||||
case 'F': [[fallthrough]];
|
||||
case 'I':
|
||||
case 'Z': [[fallthrough]];
|
||||
case 'B': [[fallthrough]];
|
||||
case 'C': [[fallthrough]];
|
||||
case 'S': [[fallthrough]];
|
||||
case 'I': [[fallthrough]];
|
||||
case 'F':
|
||||
uint32_t value = operand_stack_pop_u32(old_frame);
|
||||
operand_stack_push_u32(vm->current_frame, value);
|
||||
break;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package p;
|
||||
|
||||
class AdventDay1 {
|
||||
class AdventOfCodeDay1 {
|
||||
public static int part1() {
|
||||
int[] input = {3, 4,
|
||||
4, 3,
|
@ -1,6 +1,6 @@
|
||||
package p;
|
||||
|
||||
class AdventOfCode2024Day1 {
|
||||
class AdventOfCodeDay1_String {
|
||||
public static int part1() {
|
||||
char[] string_input = {
|
||||
'3', ' ', ' ', ' ', '4', '\n',
|
100
p/AdventOfCodeDay2.java
Normal file
100
p/AdventOfCodeDay2.java
Normal file
@ -0,0 +1,100 @@
|
||||
package p;
|
||||
|
||||
class AdventOfCodeDay2 {
|
||||
static float parse_digit(char c) {
|
||||
switch (c) {
|
||||
case '0': return 0.0f;
|
||||
case '1': return 1.0f;
|
||||
case '2': return 2.0f;
|
||||
case '3': return 3.0f;
|
||||
case '4': return 4.0f;
|
||||
case '5': return 5.0f;
|
||||
case '6': return 6.0f;
|
||||
case '7': return 7.0f;
|
||||
case '8': return 8.0f;
|
||||
case '9': return 9.0f;
|
||||
default: return -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static float fabs(float f)
|
||||
{
|
||||
if (f < 0)
|
||||
return -f;
|
||||
else
|
||||
return f;
|
||||
}
|
||||
|
||||
static float fsign(float f)
|
||||
{
|
||||
if (f < 0)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static boolean report_safe(float[] line, int length)
|
||||
{
|
||||
float last = line[0];
|
||||
float last_sign = 0.0f;
|
||||
for (int i = 1; i < length; i++) {
|
||||
float cur = line[i];
|
||||
float rate = last - cur;
|
||||
|
||||
if (fabs(rate) < 1 || fabs(rate) > 3)
|
||||
return false; // unsafe
|
||||
|
||||
float sign = fsign(rate);
|
||||
if (last_sign != 0.0f && sign != last_sign)
|
||||
return false; // unsafe
|
||||
|
||||
last_sign = sign;
|
||||
last = cur;
|
||||
}
|
||||
|
||||
return true; // safe
|
||||
}
|
||||
|
||||
static float solve(char[] input) {
|
||||
float[] line = new float[100];
|
||||
int line_ix = 0;
|
||||
int input_ix = 0;
|
||||
float num = 0.0f;
|
||||
float safe_count = 0.0f;
|
||||
|
||||
while (input_ix < input.length) {
|
||||
if (input[input_ix] == ' ' || input[input_ix] == '\n') {
|
||||
line[line_ix] = num;
|
||||
line_ix += 1;
|
||||
num = 0.0f;
|
||||
}
|
||||
if (input[input_ix] == '\n') {
|
||||
if (report_safe(line, line_ix)) {
|
||||
safe_count += 1.0f;
|
||||
}
|
||||
line_ix = 0;
|
||||
}
|
||||
float digit = parse_digit(input[input_ix]);
|
||||
if (!(digit < 0.0f)) {
|
||||
num *= 10.0f;
|
||||
num += digit;
|
||||
}
|
||||
input_ix += 1;
|
||||
}
|
||||
|
||||
return safe_count;
|
||||
}
|
||||
|
||||
public static void main() {
|
||||
char[] input = {
|
||||
'7', ' ', '6', ' ', '4', ' ', '2', ' ', '1', '\n',
|
||||
'1', ' ', '2', ' ', '7', ' ', '8', ' ', '9', '\n',
|
||||
'9', ' ', '7', ' ', '6', ' ', '2', ' ', '1', '\n',
|
||||
'1', ' ', '3', ' ', '2', ' ', '4', ' ', '5', '\n',
|
||||
'8', ' ', '6', ' ', '4', ' ', '4', ' ', '1', '\n',
|
||||
'1', ' ', '3', ' ', '6', ' ', '7', ' ', '9', '\n',
|
||||
};
|
||||
|
||||
solve(input);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user