Call popcount from Ruby / Python / C #

CodeIQ 2812 "Red and White" Problem. For an overview of the problem, refer to Explanation. In short, you can output 1 << popcount (n). If you solve in C language

n;main(){scanf("%d",&n);n=!printf("%d\n",1<<__builtin_popcount(n));}

However, it is necessary to devise to call this __builtin_popcount from other than C. As a result of the investigation, it was found that __sched_popcount () can be used on Linux and __popcountdi2 () can be used on OS X. The signature is ʻint __sched_popcount (size_t siz, long * a) , but it works for the time being even if you pass (8, long long [1] {…}) . This is because the latter is interpreted as ʻint [2] {…} in a 32-bit environment, and __sched_popcount returns the sum.

In Ruby / Python / C #, to call these functions: Magic number 8 should be avoided if possible. Python is the most accurate because it says ctypes.sizeof (ctypes.c_long).

#!/usr/bin/ruby
if RUBY_PLATFORM=~/linux/
	if true
		require 'fiddle'
		__popcount_fn=Fiddle::Function.new(Fiddle::Handle::DEFAULT['__sched_cpucount'],[Fiddle::TYPE_INT,Fiddle::TYPE_VOIDP],Fiddle::TYPE_INT)
		define_method(:popcount){|n|__popcount_fn.call(8,[n].pack('q'))}
	else
		require 'fiddle/import'
		module LibC
			extend Fiddle::Importer
			dlload 'libc.so.6'
			extern 'int __sched_cpucount(int,long long*)'
		end
		def popcount(n) LibC.__popcountdi2(8,[n]) end
	end
elsif RUBY_PLATFORM=~/darwin/
	if true
		require 'fiddle'
		__popcount_fn=Fiddle::Function.new(Fiddle::Handle::DEFAULT['__popcountdi2'],[Fiddle::TYPE_LONG],Fiddle::TYPE_INT)
		define_method(:popcount){|n|__popcount_fn.call(n)}
	else
		require 'fiddle/import'
		module LibC
			extend Fiddle::Importer
			dlload 'libSystem.dylib'
			extern 'int __popcountdi2(long)'
		end
		def popcount(n) LibC.__popcountdi2(n) end
	end
else
	def popcount(n) n==0 ? 0 : popcount(n/2)+n%2 end
end

p 1<<popcount(gets.to_i)

Since Ruby of CodeIQ is 1.9.3, do as follows. It's dirty because it has global variables, but it's unavoidable.

require 'fiddle'
require 'dl'
$__popcount_fn=Fiddle::Function.new(DL::Handle::DEFAULT['__sched_cpucount'],[Fiddle::TYPE_INT,Fiddle::TYPE_VOIDP],Fiddle::TYPE_INT)
def popcount(n) $__popcount_fn.call(8,[n].pack('q')) end
#!/usr/bin/python
import sys,ctypes
if sys.version_info[0]>=3:
	raw_input=input
	xrange=range

if sys.platform.startswith('linux'):
	libc=ctypes.cdll.LoadLibrary('libc.so.6')
	popcount=lambda n:libc.__sched_cpucount(ctypes.sizeof(ctypes.c_long),(ctypes.c_long*1)(n))
elif sys.platform=='darwin':
	libc=ctypes.cdll.LoadLibrary('libSystem.dylib')
	popcount=lambda n:libc.__popcountdi2(n)
else:
	popcount=lambda n:0 if n==0 else popcount(n/2)+n%2

print(1<<popcount(int(raw_input())))
using System;
using System.Runtime.InteropServices;
 
class CodeIQ2812{
	[DllImport("msvcrt",CallingConvention=CallingConvention.Cdecl)]static extern int __popcountdi2(long n);
	[DllImport("msvcrt",CallingConvention=CallingConvention.Cdecl)]static extern int __sched_cpucount(int n, long[] a);

	static int popcount(long n){
		//Comment out appropriately as there is no way to determine at compile time
		//return __popcountdi2(n);
		return __sched_cpucount(8,new long[]{n});
		//return n==0 ? 0 : popcount(n/2)+(int)(n%2);
	}
	static void Main(){
		int n=int.Parse(Console.ReadLine());
		Console.WriteLine(1<<popcount(n));
	}
}

If you're wondering if the marshalling overhead may be greater, it's probably a hit. Use this method systematically.

Recommended Posts

Call popcount from Ruby / Python / C #
Call C from Python with DragonFFI
Call C / C ++ from Python on Mac
Call c language from python (python.h)
Call a Python script from Embedded Python in C ++ / C ++
[Python] How to call a c function from python (ctypes)
Call Matlab from Python to optimize
Call C language functions from Python to exchange multidimensional arrays
Call a Python function from p5.js.
Tips for calling Python from C
Execute Python code from C # GUI
Run Python scripts synchronously from C #
Call python from nim with Nimpy
How to call Python or Julia from Ruby (experimental implementation)
Call your own C language shared library from Python using ctypes
msgpack deserialization performance comparison (C ++ / Python / Ruby)
Try calling Python from Ruby with thrift
Generate C language from S-expressions in Python
Use C ++ functions from python with pybind11
Call a command from Python (Windows version)
C language to see and remember Part 2 Call C language from Python (argument) string
sql from python
C language to see and remember Part 1 Call C language from Python (hello world)
python C ++ notes
python, openFrameworks (c ++)
MeCab from Python
C language to see and remember Part 4 Call C language from Python (argument) double
C language to see and remember Part 5 Call C language from Python (argument) Array
Run a Python script from a C # GUI application
Create a C array from a Python> Excel sheet
Wrap C with Cython for use from Python
Call Python library for text normalization from MATLAB
Python vs Ruby "Deep Learning from scratch" Summary
Wrap C ++ with Cython for use from Python
I want to make C ++ code from Python code!
paiza POH ec-campaign (C # / Java / Python / Ruby) # paizahack_01
Call Polly from the AWS SDK for Python
An easy way to call Java from Python
C language to see and remember Part 3 Call C language from Python (argument) c = a + b
Use thingsspeak from python
Touch MySQL from Python 3
Operate Filemaker from Python
Use fluentd from python
Python C / C ++ Extension Pattern-Pointer
Changes from Python 2 to Python 3.0
Python from or import
Let's call your own C ++ library with Python (Preferences)
Use MySQL from Python
Ruby, Python and map
Run python from excel
Install python from source
Execute command from Python
Python points from the perspective of a C programmer
Next Python in C
MessagePack-Call Python (or Python to Ruby) methods from Ruby using RPC
Operate neutron from Python!
Python and Ruby split
Use MySQL from Python
Operate LXC from Python
Manipulate riak from python
Force Python from Fortran